建议使用TairBloom方式
public void dmpWriteRedis(String requestid, String key, String hashKey) {
if (StringUtils.isNotBlank(requestid)) {
//设置redis服务器数量:3
int requestidHash = oConvertUtils.toHash(requestid, 3);
StringRedisTemplate redisServiceReq;
switch (requestidHash) {
case 1:
redisServiceReq = redisTemplateDspDmpDb2_1;
break;
case 2:
redisServiceReq = redisTemplateDspDmpDb2_2;
break;
default:
redisServiceReq = redisTemplateDspDmpDb2_3;
}
String BLOOM_FILTER_NAME = "BLSL-" + Time.datatime();
// 判断布隆过滤器是否存在
boolean filterExists = redisServiceReq.hasKey(BLOOM_FILTER_NAME);
if (!filterExists) {
// 创建布隆过滤器(如果不存在)
redisServiceReq.execute((RedisCallback<Object>) connection -> {
connection.execute("BF.RESERVE", BLOOM_FILTER_NAME.getBytes(StandardCharsets.UTF_8), "0.01".getBytes(StandardCharsets.UTF_8), "1000000".getBytes(StandardCharsets.UTF_8));
return null;
});
// 设置布隆过滤器的过期时间
redisServiceReq.expire(BLOOM_FILTER_NAME, 1, TimeUnit.DAYS);
}
// 检查 requestid 是否在布隆过滤器中
Long execute = (Long) redisServiceReq.execute((RedisCallback<Object>) connection -> {
return connection.execute("BF.EXISTS", BLOOM_FILTER_NAME.getBytes(StandardCharsets.UTF_8), requestid.getBytes(StandardCharsets.UTF_8));
});
if (null == execute || execute == 0) {
// 如果 requestid 不在布隆过滤器中,则添加
redisServiceReq.execute((RedisCallback<Object>) connection -> {
return connection.execute("BF.ADD", BLOOM_FILTER_NAME.getBytes(StandardCharsets.UTF_8), requestid.getBytes(StandardCharsets.UTF_8));
});
if (StringUtils.isNotBlank(hashKey)) {
//设置dmp-redis服务器数量:3
int hash = oConvertUtils.toHash(key, 3);
StringRedisTemplate redisService;
switch (hash) {
case 1:
redisService = redisTemplateDspDmpDb2_1;
break;
case 2:
redisService = redisTemplateDspDmpDb2_2;
break;
default:
redisService = redisTemplateDspDmpDb2_3;
}
redisService.opsForHash().increment(key, hashKey, 1);
redisService.expire(key, 180, TimeUnit.DAYS);
}
}
}
}
// 将字符串转成hash值 对redis集群数量取余并加一(保证最终值为 1~redis集群数量) 本算法用于redis负载均衡
public static int toHash(String key, int redisNum) {
int arraySize = 11113; // 数组大小一般取质数
int hashCode = 0;
for (int i = 0; i < key.length(); i++) { // 从字符串的左边开始计算
int letterValue = key.charAt(i) - 96;// 将获取到的字符串转换成数字,比如a的码值是97,则97-96=1
// 就代表a的值,同理b=2;
hashCode = ((hashCode << 5) + letterValue) % arraySize;// 防止编码溢出,对每步结果都进行取模运算
}
return (Math.abs(hashCode) % redisNum) + 1;
}

8002

被折叠的 条评论
为什么被折叠?



