Redis的使用建议
如何使用 Redis 更节省内存?
- 控制 key 的长度
- 例如,原有的 key 为 user:order:123,则可以优化为 u:od:123
- 避免存储 bigkey
- String:大小控制在 10KB 以下
- List/Hash/Set/ZSet:元素数量控制在1万以下
- 把 Redis 当作缓存使用
- 尽可能地都设置「过期时间」
- 让 Redis 中只保留经常访问的「热数据」
- 客户端采用snappy、gzip等压缩算法,对键值压缩后存储到redis
如何持续发挥 Redis 的高性能?
- 避免使用大value(10k以上就算大value,50k会记录)
- 开启 lazy-free 机制
- Redis在删除一个bigkey时,释放内存的耗时操作,将会放到后台线程中去执行
- 不使用复杂度过高的命令
- 复杂度过高消耗CPU时间更长,主线程中的其它请求只能等待
- 避免执行例如 SORT、SINTER、SINTERSTORE、ZUNIONSTORE、ZINTERSTORE 等聚合类命令
- 执行 O(N) 命令时,关注 N 的大小
- 先查询数据元素的数量(LLEN/HLEN/SCARD/ZCARD)
- 元素数量较少,可一次性查询全量数据
- 元素数量非常多,分批查询数据(LRANGE/HASCAN/SSCAN/ZSCAN)
- 关注 DEL 时间复杂度
- List类型:执行多次 LPOP/RPOP,直到所有元素都删除完成
- Hash/Set/ZSet类型:先执行 HSCAN/SSCAN/SCAN 查询元素,再执行 HDEL/SREM/ZREM 依次删除每个元素
- 禁止使用 KEYS/FLUSHALL/FLUSHDB 命令
- 从全表扫描变为点查/部分range, 虽然hash结构中field太多也会慢,但比keys性能提升一个到两个数量级
- 会长时间阻塞 Redis 主线程,危害极大
- SCAN 替换 KEYS
- 4.0+版本可使用 FLUSHALL/FLUSHDB ASYNC,清空数据的操作放在后台线程执行
Redis的使用建议
- 推荐:
- 确定场景,是缓存(cache)还是存储型;
- Cache的使用原则是:“无它也可,有它更强”;
- 永远不要强依赖Cache,它会丢,也会被淘汰;
- 优先设计合理的数据结构和逻辑;
- 设计避免bigKey,就避免了80%的问题;
- Keyspace能分开,就多申请几个Redis实例;
- pubsub不适合做消息分发;
- 尽量避免用lua做事务。
- 不建议:
- 我的服务对RT很敏感。>> 低RT能让我的服务运行的更好;
- 我把存储都公用在一个redis里。>> 区分cache和内存数据库用法,区分应用;
- 我有一个大排行榜/大集合/大链表/消息队列;我觉得服务能力足够了。>> 尽量拆散,服务能力不够可通过分布式集群版可以打散;
- 我有一个特别大的Value,存在redis里,访问能好些。>> redis吞吐量有瓶颈。
常见问题
- 当连接池被checkout完,就会爆没有连接的异常:"Could not get a resource from the pool",这是非常常见的错误,有恶性循环的逻辑在里面。比如说服务端返回的慢,连接池的连接就会创建的很快,用户很容易达到1万条,创建的连接越多,性能越差,返回越慢,服务容易血崩。

浙公网安备 33010602011771号