其他
阿里官方 Redis 开发规范
点击上方 Java后端,选择 设为星标
优质文章,及时送达
本文主要介绍在使用阿里云 Redis 的开发规范,从下面几个方面进行说明。
键值设计 命令使用 客户端使用 相关工具
一、键值设计
1、key 名设计
可读性和可管理性
ugc:video:1
简洁性
user:{uid}:friends:messages:{mid}简化为u:{uid}:fr:m:{mid}。
不要包含特殊字符
2、value 设计
拒绝 bigkey
选择适合的数据类型
set user:1:name tom
set user:1:age 19
set user:1:favor football
hmset user:1 name tom age 19 favor football
控制 key 的生命周期
二、命令使用
1、O(N) 命令关注 N 的数量
2、禁用命令
3、合理使用 select
4、使用批量操作提高效率
原生命令:例如 mget、mset。 非原生命令:可以使用 pipeline 提高效率。
原生是原子操作,pipeline 是非原子操作。 pipeline 可以打包不同的命令,原生做不到 pipeline 需要客户端和服务端同时支持。
5、不建议过多使用 Redis 事务功能
6、Redis 集群版本在使用 Lua 上有特殊要求
7、monitor 命令
三、客户端使用
1、避免多个应用使用一个 Redis 实例
2、使用连接池
执行命令如下:
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();
}
3、熔断功能
4、合理的加密
5、淘汰策略
allkeys-lru:根据 LRU 算法删除键,不管数据有没有设置超时属性,直到腾出足够空间为止。 allkeys-random:随机删除所有键,直到腾出足够空间为止。 volatile-random: 随机删除过期键,直到腾出足够空间为止。 volatile-ttl:根据键值对象的 ttl 属性,删除最近将要过期数据。如果没有,回退到 noeviction 策略。 noeviction:不会剔除任何数据,拒绝所有写入操作并返回客户端错误信息 "(error) OOM command not allowed when used memory",此时 Redis 只响应读操作。
四、相关工具
1、数据同步
2、big key 搜索
3、热点 key 寻找
五、删除 bigkey
下面操作可以使用 pipeline 加速。 redis 4.0 已经支持 key 的异步删除,欢迎使用。
1、Hash 删除: 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);
}
2、List 删除: 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);
}
3、Set 删除: 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);
}
4、SortedSet 删除: zscan + zrem
public void delBigZset(String host, int port, String password, String bigZsetKey) {
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<Tuple> scanResult = jedis.zscan(bigZsetKey, cursor, scanParams);
List<Tuple> tupleList = scanResult.getResult();
if (tupleList != null && !tupleList.isEmpty()) {
for (Tuple tuple : tupleList) {
jedis.zrem(bigZsetKey, tuple.getElement());
}
}
cursor = scanResult.getStringCursor();
} while (!"0".equals(cursor));
//删除bigkey
jedis.del(bigZsetKey);
}
如果看到这里,说明你喜欢这篇文章,请 转发、点赞。同时 标星(置顶)本公众号可以第一时间接受到博文推送。
推荐阅读
获取方式:点“ 在看,关注公众号 Java后端 并回复 777 领取,更多内容陆续奉上。
喜欢文章,点个在看