民工兄Redis教程(二十三):阿里云开发规范
本文介绍了使用阿里云Redis的开发规范,包括键值设计、命令使用、客户端使用、相关工具等。文章中,可以减少使用Redis进程带来的问题。
键值设计
键名设计
可读性和可管理性
以业务名称(或数据库名称)作为前缀(避免键冲突)并用冒号分隔,例如业务名称Name:id
ugc:video:1
简单性
在安全语义的假设下,控制密钥的长度。当key很多的时候,内存的占用就不能忽略了。例如:
user:{uid}:friends:messages:{mid}简化为u:{uid}
不要插入特殊字符
反对示例:插入空格、换行、单双引号等转义字符
value设计
拒绝bigkey(防止网卡传输速度变慢)
类型string控制在10KB以内,hash、list、set、zset元素个数不要超过5000个。
反例:包含200万个元素的list。
bigkey,不是字符串,不要用del删除,使用hscan、sscan、zscan逐渐删除,注意避免bigkey过期时间自动删除的问题(比如200万
zset会设置过期1小时,就会开始del操作,这会造成死锁,对于慢查询不会出现该操作(可以检查延迟))。搜索方法和删除方法
选择合适的数据类型。 ?控制key生命周期,redis不是垃圾桶。
设置过期时间,建议使用expire(如果条件允许,可以划分过期时间,防止集中过期)。对于未过期的数据,重点关注空闲时间。命令
使用命令
O(N) 来聚焦数字 N
例如,hgetall、lrange、smembers、zrange、sinter 等。它们并不是不能用,但是N的值需要明确。如果您有遍历需求,可以使用 hscan、sscan 或 zscan 代替。
禁用命令
禁用键、flushall、flushdb 等的使用。在线的。通过 redis 重命名机制禁用命令或使用扫描顺序处理它们。
合理使用所选
Redis多数据库较弱,用数字来区分。许多客户的支持很差。同时多数据库多业务其实都是单线程的,会造成干扰。
使用批处理操作提高效率
- 原生命令:如mget、mset。
- 非原生命令:您可以使用管道来提高效率。
但是要注意批量操作中检查元素的数量(比如500以内,这其实和元素的字节数有关)。
注意两者之间的区别:
- Native 是原子操作,pipe 是非原子操作。
- Pipeline 可以包装各种原生无法执行的命令。
- 管道必须得到客户端和服务器的支持。
不建议过于频繁使用Redis事务功能)。 Redis集群版本对使用Lua有特殊要求
1。所有密钥都应通过 KEYS 字段。 redis.call/pcall 中调用的 Redis 命令且 key 位置必须是 KEYS 数组,否则直接返回错误,“-ERR bad lua script for redis cluster, all keys use by script should be pass using KEYSrn array”
2.所有按键必须在1个插槽中,否则会出错,“- ERR eval/evalsha命令按键必须在同一个插槽中”
monitor命令
使用monitor命令时,如有必要,请注意不要使用许久。
客户端使用
避免多个应用程序使用单个Redis实例
正面示例:拆分不相关的存储并将公共数据用作服务。
使用连接池数据库
可以有效控制连接,同时提高效率。标准使用:
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
//具体的命令
jedis.executeCommand()
} catch (Exception e) {
logger.error("op key {} error: " + e.getMessage(), key, e);
} finally {
//注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
if (jedis != null)
jedis.close();
}
阻断功能
高并发时,建议客户端添加断路器功能(如Netflix hystrix)
合理加密
必要时使用合理的密码和SSL加密(支持阿里云Redis)
淘汰策略
根据您的业务类型选择maxmemory-policy(最大内存淘汰策略),设置过期时间。
默认策略是 volatile-lru,即超过最大内存时,会使用 lru 算法淘汰过期的 key,保证过期的数据不被删除,但可能存在 OOM 的问题。
其他策略如下:
- allkeys-lru:根据LRU算法删除key,无论数据是否设置了超时属性,直到释放足够的空间。
- allkeys-random:随机删除所有键,直到释放足够的空间。
- 易失性随机:随机删除过期的键,直到释放足够的空间。
- volatile-ttl:根据键值对象的ttl属性删除最近过期的数据。如果没有,请返回驱逐策略。
- discard:不会删除任何数据,所有写操作都会被拒绝,并返回客户端错误信息“(error) OOM command is not allowed while using memory”。目前,Redis 只会响应读操作。
相关工具
数据同步
redis之间的数据同步可以使用:redis-port
大键查找
Horedis大键查找‼内部实现使用monitor。建议短时间使用Facebook的redis-fain。阿里云Redis在内核层面解决了热键问题
删除bigkey
- 以下操作可以使用管道加速。
- Redis 4.0已经支持异步key删除,欢迎使用。
清除散列:hscan + hdel
public void delBigHash(String host, int port, String password, String bigHashKey) {
Jedis jedis = new Jedis(host, port);
if (password != null && !"".equals(password)) {
jedis.auth(password);
}
ScanParams scanParams = new ScanParams().count(100);
String cursor = "0";
do {
ScanResult<Entry<String, String>> scanResult = jedis.hscan(bigHashKey, cursor, scanParams);
List<Entry<String, String>> entryList = scanResult.getResult();
if (entryList != null && !entryList.isEmpty()) {
for (Entry<String, String> entry : entryList) {
jedis.hdel(bigHashKey, entry.getKey());
}
}
cursor = scanResult.getStringCursor();
} while (!"0".equals(cursor));
//删除bigkey
jedis.del(bigHashKey);
}
清除列表:ltrim
public void delBigList(String host, int port, String password, String bigListKey) {
Jedis jedis = new Jedis(host, port);
if (password != null && !"".equals(password)) {
jedis.auth(password);
}
long llen = jedis.llen(bigListKey);
int counter = 0;
int left = 100;
while (counter < llen) {
//每次从左侧截掉100个
jedis.ltrim(bigListKey, left, llen);
counter += left;
}
//最终删除key
jedis.del(bigListKey);
}
清除集合:sscan + srem
public void delBigSet(String host, int port, String password, String bigSetKey) {
Jedis jedis = new Jedis(host, port);
if (password != null && !"".equals(password)) {
jedis.auth(password);
}
ScanParams scanParams = new ScanParams().count(100);
String cursor = "0";
do {
ScanResult<String> scanResult = jedis.sscan(bigSetKey, cursor, scanParams);
List<String> memberList = scanResult.getResult();
if (memberList != null && !memberList.isEmpty()) {
for (String member : memberList) {
jedis.srem(bigSetKey, member);
}
}
cursor = scanResult.getStringCursor();
} while (!"0".equals(cursor));
//删除bigkey
jedis.del(bigSetKey);
}
清除排序文件:https://zscan + zourcel ky2xn
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。