Redis:性能优化之Redis使用的规范

【关于作者】

关于作者,目前在蚂蚁金服搬砖任职,在支付宝营销投放领域工作了多年,目前在专注于内存数据库相关的应用学习,如果你有任何技术交流或大厂内推及面试咨询,都可以从我的个人博客(https://0522-isniceday.top/)联系我

1.键值对使用规范

1.1.key的命名规范

  • 按照业务用于区分key,使用冒号进行分割

    这样能够将相同的业务key放到一个db,减少切换db的开销

    规范的命令有利于key的匹配,keys命令。例如客户端缓存的key的监控、scan等操作

  • 控制key的长度

    redis中key也是字符串存储,因此也是使用SDS进行存储,因此控制key的长度有利于节省内存空间
    img

1.2.规避使用bigkey

Redis针对读写命令的处理是单线程的,因此bigkey的操作会阻塞线程,尤其是针对时间复杂度为O(n)的数据结构进行并交集、全量查询等耗时的操作

bigkey也分为两种:

  • 键值对的value本身就很大,例如String本身就有10mb,建议把String的大小控制在10kb(10 * 1024字节,大部分编码格式下,一个中文占用4个字节,字母占用2个字节),如果value确实很大,此时我们可以考虑将数据进行压缩
  • 集合类型的元素数量特别多,建议控制在1万个元素个数之下,可通过拆分list的方式

Redis的4种集合类型List、Hash、Set和Sorted Set,在集合元素个数小于一定的阈值时,会使用内存紧凑型的底层数据结构(压缩列表)进行保存,从而节省内存。例如,假设Hash集合的hash-max-ziplist-entries配置项是1000,如果Hash集合元素个数不超过1000,就会使用ziplist保存数据。

1.3.采取高效序列化方法和压缩方法

但是,不同的序列化方法,在序列化速度和数据序列化后的占用内存空间这两个方面,效果是不一样的。比如说,protostuff和kryo这两种序列化方法,就要比Java内置的序列化方法(java-build-in-serializer)效率更高。

此外,业务应用有时会使用字符串形式的XML和JSON格式保存数据。

这样做的好处是,这两种格式的可读性好,便于调试,不同的开发语言都支持这两种格式的解析。

缺点在于,XML和JSON格式的数据占用的内存空间比较大。为了避免数据占用过大的内存空间,我建议使用压缩工具(例如snappy或gzip),把数据压缩后再写入Redis,这样就可以节省内存空间了

1.4.使用整数对象共享池

Redis内部维护了09999这一万个整数对象,并将其作为对象池使用,因此再业务允许的情况下,能用整数就用整数,因为如果使用到了整数,不管有多少键值对,其实真是的引用地址都是一个,这样可以大大的节省空间哟

但是整数共享池在某些场景不会起作用:

  • 使用了设置maxmemory及LRU淘汰策略的情形下,LRU需要统计键值对的使用时间,如果都使用的一个对象,那么就无法统计
  • 集合类型采取压缩列表的方式存储,压缩列表本质还是一个数组,数组中都是直接存储元素而不是指针,判断整数对象的共享情况效率低

2.数据保存规范

2.1.使用redis保存热数据

redis保存热数据能够提供高性能的访问,如果写场景比较多的话,也需要将数据同步的开销算进去,还有就是需要考虑

缓存失效导致的缓存击穿,因为尽量将数据不设置过期时间,还有就是可以将同步缓存的操作用分布式锁锁住,这样就不会有大量请求打向数据库了🐶

2.2.不同的业务数据分实例存储

把不同的业务数据放到不同的 Redis 实例中。这样一来,既可以避免单实例的内存使用量过大,也可以避免不同业务的操作相互干扰

2.3.数据保存时,设置过期时间

根据业务的时长,设置合理的过期时间,因为如果不设置过期时间,redis实例内存满了会触发数据淘汰,这个时候会释放内存的操作会阻塞主进程,并且设置过期时间时候尽量避免批量过期的情况

2.4.控制实例的容量

建议设置在2~6GB,实例数据量过大会加大RDB快照的fork的耗时,以及主从实例数据同步的耗时

3.命令使用规范

3.1.线上禁用部分命令

Redis是单线程处理读写命令,如果一些耗时的命令或操作会阻塞主进程,其中包括:

  • KEYS:返回匹配key内容的key,这个操作会扫描全局哈希表,严重阻塞redis的主进程,可用SCAN命令进行替代
  • FLUSHALL,删除Redis实例上的所有数据,如果数据量很大,会严重阻塞Redis主线程,可以加上ASYNC,让redis后台线程异步删除
  • FLUSHDB,删除当前数据库中的数据,如果数据量很大,同样会阻塞Redis主线程,解决方案同FLUSHALL

线上如何禁用呢?管理员用rename-command命令在配置文件中对这个命令重命名,让客户端无法使用

3.2.慎用MONITOR命令

Redis使用MONITOR命令后,会持续监控后续命令的执行情况,这个时候会将执行情况输入到输出缓存区,如果输出缓冲区满了之后就会影响Redis性能及造成redis崩溃

建议不使用MONITOR命令,除非十分需要监测某些命令的执行,可以短时间内使用

3.3.慎用全量操作的命令

对于集合数据类型而言,慎重使用SCAN等操作,因为这些操作会对底层的数据进行全表扫描,如果数据量比较大则会阻塞主线程

解决方案如下:

  • 使用SSCAN、HSCAN分批返回集合中的数据
  • 将结构数据看是否能够在符合业务的情况下进行拆分,例如根据不同的维度拆分
  • 如果使用hash存储的对象的键值信息,并且每次都是全量返回的话,可以使用String的方式进行存储,将value序列化为JSON的形式

4.运维层面

  • 建议部署主从集群,并分布在不同机器上,slave 设置为 readonly
  • 实例设置最大连接数,防止过多客户端连接导致实例负载过高,影响性能
  • 设置合理的 slowlog 阈值,并对其进行监控,slowlog 过多需及时报警
  • 设置合理的 repl-backlog,降低主从全量同步的概率,具体的参数设置可看:
  • 设置合理的 slave client-output-buffer-limit,避免主从复制中断情况发生(缓冲区溢出)
  • 调整 maxmemory 时,注意主从节点的调整顺序,顺序错误会导致主从数据不一致
  • 对实例部署监控,采集 INFO 信息时采用长连接,避免频繁的短连接
  • 做好实例运行时监控,重点关注 expired_keys、evicted_keys、latest_fork_usec,这些指标短时突增可能会有阻塞风险

img

强制:表示如果不遵守会给redis带来极大的性能影响

推荐:代表可以直接运用在实践中

建议:结合业务场景考量再决定是否使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Redis设计规范可以根据具体的使用场景和需求来确定,下面是一些常见的设计规范: 1. 键的命名规范:选择一个有意义的键名,以便于维护和理解。可以使用统一的命名前缀来区分不同的业务或模块。 2. 数据结构的选择:根据实际需求选择适合的数据结构来存储数据。Redis支持多种数据结构,如字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(sorted set)等。 3. 内存优化:由于Redis是基于内存的数据库,需要合理使用内存。可以通过设置过期时间、压缩数据、使用合适的数据结构等方式来减少内存占用。 4. 数据持久化:Redis支持两种方式的数据持久化,即照(snapshotting)和AOF(Append-Only File)。可以根据实际情况选择合适的持久化方式,并设置适当的保存频率和策略。 5. 高可用性和容灾:可以通过主从复制(replication)和哨兵(sentinel)机制来实现Redis的高可用性和容灾。设置合适的主从配置和哨兵监控可以保证系统的稳定性和可用性。 6. 性能优化:可以通过批量操作、管道(pipeline)、使用连接池等方式来提高Redis的性能。同时,合理设置连接超时时间、最大连接数等参数也能够优化性能。 7. 安全性保护:为了保护数据的安全性,可以通过密码认证、限制访问IP、使用SSL加密等方式加强安全性。 需要根据具体场景和需求进行设计和调优,以上只是一些常见的设计规范,具体还需根据实际情况来确定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈哈哈张大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值