分布式缓存长 key 影响性能怎么办?一文讲透如何优化!

一、背景

有个需求需要将 SQL 语句作为分布式缓存的 key。
但是这样做会导致 key 太长。key 太长会有一些缺点。
但是 key 太长的问题也是可以解决的。
本文将详细讲述 key 太长的缺点和解决方案,希望对大家有帮助。

二、Key 太长的缺点

通常来说 SQL 作为 Key 太长,会有诸多缺点:

  • Key太长会占用更多的内存空间,降低缓存的效率和命中率。
  • Key太长会增加网络传输的开销,影响缓存的响应速度和吞吐量。
  • Key太长会导致数据分片不均匀,增加缓存服务器之间的负载差异和数据迁移的成本。
  • Key太长会增加缓存的管理和维护的难度,比如删除、更新、监控等操作。

因此,建议使用合理的Key设计规范,避免使用过长或者不必要的前缀、后缀、分隔符等。

三、解决方案

3.1 Hash (解决冲突问题)

可以使用哈希算法(如 MD5、SHA-1 等)将 SQL 语句转换成固定长度的字符串作为缓存 key。这种方式可以缩短 key 的长度,减小缓存空间占用,同时也可以提高查找效率。
但是,哈希算法可能存在冲突,需要注意缓存 key 的唯一性。

如何解决还冲突带来的唯一性问题?

  • 加前缀,比如不同的租户、店铺的ID 或者 Code 作为 Key 的前缀,可以极大降低冲突的概率。
  • 可以自定义值的结构
    (1)将 SQL 存储在 Value 对象中,用于二次确认。
    (2)如果原始的值是单个对象,可以定义为集合为。
    通过 hash 值作为 key 读取出来值的时候对比当前 Sql 和 Value 中存储的 SQL 是否一致。
    如果一致说明没有 Hash 冲突;如果不一致说明存在 hash 冲突,可以将新值放到集合中,读取时遍历集合取出对应的值即可。

伪代码如下:

public class Value{
    
    
  String sql;
  Object value;
}

public class CacheValueWrapper{
    
    
    // 不冲突时存这里
    Value value;
    
    // 冲突时存这里
    List<Value> values;

    Value getValue(String sql){
    
    
       // 先匹配 value 

       // 再匹配 values
    }
}

3.2 语句映射(转化成唯一的值)

可以借助表的唯一键的特性。
新建一个映射表,包括 SQL 字符串、业务 Code (业务 ID)。

sql id
select * from user where id=21 10086
select name,age from student where id=22 10087

业务Code 或者 业务 ID 可以使用数据库自增的特性也可以使用分布式 ID 生成器。
SQL 字符串设置为唯一键。
先通过 SQL 来查询,如果直接使用,如果表中没有这个 SQL 值则插入。

就可以将对应的业务 Code 或 业务ID 作为缓存 Key 的重要组成部分。

缓存Key: some_biz_prefix_10086

四、总结

本文提供一些解决 Key 过长的思路,希望对遇到相似问题的同学有启发。


创作不易,如果本文对你有帮助,欢迎点赞、收藏加关注,你的支持和鼓励,是我创作的最大动力。
在这里插入图片描述

欢迎加入我的知识星球,知识星球ID:15165241 一起交流学习。
https://t.zsxq.com/Z3bAiea 申请时标注来自CSDN。

欢迎加入我们的 slack 工作区,在里面可以对ai 和我进行提问。
https://join.slack.com/t/ai-yx51081/shared_invite/zt-1t8cp1lk3-ZMAFutZcN3PCW~8WQDGjPg

猜你喜欢

转载自blog.csdn.net/w605283073/article/details/130354330