Redis 正确使用小技巧

①正确设置过期时间

 

把这个放在第一位是因为这里实在是有太多坑。

 

如果你不设置过期时间,那么你的 Redis 就成了垃圾堆,假以时日你领导看到了告警,再看一下你的代码,估计你可能就 “没了”!

 

如果你设置了过期时间,但是又设置了特别长,比如两个月,那么带来的问题就是极有可能你的数据不一致问题会变得特别棘手。

 

我就遇到过这种,用户信息缓存中包含了除基本信息外的各种附加属性,这些属性又是随时会变的,在有变化的时候通知缓存进行更新,但是这些附加信息是在各个微服务中,服务之间调用总会有失败的时候,只要发生那就是缓存与数据不一致之日。

 

但是缓存又是 2 个月过期一次,遇到这种情况你能怎么办,只能手动删除缓存,重新去拉数据。

 

所以过期时间设置是很有技巧性的。

 

②批量操作使用 Pipeline 或者 Lua 脚本

 

使用 Pipeline 或 Lua 脚本可以在一次请求中发送多条命令,通过分摊一次请求的网络及系统延迟,从而可以极大的提高性能。

 

③大对象尽量使用序列化或者先压缩再存储

 

如果存储的值是对象类型,可以选择使用序列化工具比如 protobuf,Kyro。对于比较大的文本存储,如果真的有这种需求,可以考虑先压缩再存储,比如使用 snappy 或者 lzf 算法。

 

④Redis 服务器部署尽量与业务机器同机房

 

如果你的业务对延迟比较敏感,那么尽量申请与当前业务机房同地区的 Redis 机器。同机房 Ping 值可能在 0.02ms,而跨机房能达到 20ms。当然如果业务量小或者对延迟的要求没有那么高这个问题可以忽略。

 

Redis 服务器内存分配策略的选择:

 

首先我们使用 info 命令来查看一下当前内存分配中都有哪些指标:

info
$2962
# Memory
used_memory:325288168         
used_memory_human:310.22M  #数据使用内存
used_memory_rss:337371136
used_memory_rss_human:321.74M #总占用内存
used_memory_peak:327635032
used_memory_peak_human:312.46M  #峰值内存
used_memory_peak_perc:99.28%
used_memory_overhead:293842654
used_memory_startup:765712
used_memory_dataset:31445514
used_memory_dataset_perc:9.69%
total_system_memory:67551408128
total_system_memory_human:62.91G   # 操作系统内存
used_memory_lua:43008
used_memory_lua_human:42.00K
maxmemory:2147483648
maxmemory_human:2.00G
maxmemory_policy:allkeys-lru    # 内存超限时的释放空间策略
mem_fragmentation_ratio:1.04    # 内存碎片率(used_memory_rss / used_memory)
mem_allocator:jemalloc-4.0.3    # 内存分配器
active_defrag_running:0
lazyfree_pending_objects:0

 

上面我截取了 Memory 信息。根据参数:mem_allocator 能看到当前使用的内存分配器是 jemalloc。

 

Redis 支持三种内存分配器:tcmalloc,jemalloc 和 libc(ptmalloc)。

 

在存储小数据的场景下,使用 jemalloc 与 tcmalloc 可以显著的降低内存的碎片率。

 

根据这里的评测:

https://matt.sh/redis-quicklist

 

保存 200 个列表,每个列表有 100 万的数字,使用 jemalloc 的碎片率为 3%,共使用 12.1GB 内存,而使用 libc 时,碎片率为 33%,使用了 17.7GB 内存。

 

但是保存大对象时 libc 分配器要稍有优势,例如保存 3000 个列表,每个列表里保存 800 个大小为 2.5k 的条目,jemalloc 的碎片率为 3%,占用 8.4G,而 libc 为 1%,占用 8GB。

 

现在有一个问题:当我们从 Redis 中删除数据的时候,这一部分被释放的内存空间会立刻还给操作系统吗?

 

比如有一个占用内存空间(used_memory_rss)10G 的 Redis 实例,我们有一个大 Key 现在不使用需要删除数据,大约删了 2G 的空间。那么理论上占用内存空间应该是 8G。

 

如果你使用 libc 内存分配器的话,这时候的占用空间还是 10G。这是因为 malloc() 方法的实现机制问题,因为删除掉的数据可能与其他正常数据在同一个内存分页中,因此这些分页就无法被释放掉。

 

当然这些内存并不会浪费掉,当有新数据写入的时候,Redis 会重用这部分空闲空间。

 

如果此时观察 Redis 的内存使用情况,就会发现 used_memory_rss 基本保持不变,但是 used_memory 会不断增长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值