Redis是一个我们常用的高性能组件,在使用Redis的场景下通常我们会对性能较高要求,Redis通常情况能满足我们的要求,但某些情况下我们还会对Redis进行进一步的优化;

       谈优化前我们首先要对Redis要有一个全局的认识,Redis是单线程,Redis作为KV数据库包括访问框架,操作模块,索引模块,存储模块;Redis的访问方式包括UNIX套接字和TCP;操作模块和数据结构相关,包括string,list,set,Hash,Sorted Set; 索引模块是为了更迅速的通过key定位到value,Redis采用的索引方式是哈希表(其它常用的索引方式还包括B+树,字典树,跳表等); 存储模块主要是负责分配及持久化,Redis支持的持久化方式包括RDB(快照)以及AOF(日志);

       索引模块的优化思路在于提高哈希表定位元素的速度,key增多会导致哈希表冲突增加,进而降低执行速度,对于除string外的复杂数据结构,还会对具体值进行二次查找,因此选择合适的数据结构也非常重要,具体可以参考极客时间蒋德均老师的<Redis核心技术与实战>课程;访问框架的优化思路在提高通信速度;

Redis的优化思路:

1.分库;

   多数人并不推荐分库,但是有些场景分库是能够提到立竿见影的效果的;如果代码中不得不用较多的keys操作,而业务又可以隔离,能显著提升性能;其底层优化逻辑在于keys操作无法通过哈希表来定位元素,这时定位元素的时间复杂度便不是0(1),而是0(n); 分库对于删除redis中的数据也是比较友好的;

2.集群+哈希;多线程版本分支keydb;

     redis是单线程也便意味着不能使用多核;当单核不能满足性能要求是便需要考虑使用上多核,毕竟当redis成为系统的瓶颈时,业务一定程度上串行了;多redis需要在业务层上对数据进行分离,如根据key哈希到不同的redis中存储;如果业务数据无法进行拆分,keydb也是不错的选择(其作者更愿意为了性能提高实现的复杂性),其本身做多线程处理,其使用了reuseport特性,多个worker线程处理;

3.可靠性没特别高要求的不要持久化;

4.使用redis的lazy-free功能延迟删除;

     lazy-free时redis4以后的功能,其将删除操作放到非主线程进行操作,这样可以避免大量删除造成的性能波动;

5.redis多实例;

    某些情况下多个redis或者将redis编译为动态库链接到系统中未尝不可进行考虑;使用系统多个程序使用不同的redis,并且对性能有极高要求;

6.排查数据是否合适放在redis中

      如数据使用频繁而不会变动是否可以写在共享内存中,共享内存是最快的进程通信方式,不会触发系统调用;只读不写是最适合共享内存的应用场景了;

7.避免使用keys操作;

      keys会导致查找的时间复杂度为0(n);

      其它复杂度命令也要少用;Redis 命令参考 — Redis 命令参考有给出每个命令的时间复杂度;

8.本地使用UNIX套接字而非TCP;

9.使用DPDK优化通信;

     DPDK是对通信的优化,加上用户态协议栈,直接在用户态完成通信,不过需要代码进行改动调用DPDK接口;目前腾讯云的f-stack已经将redis的DPDK版本实现;

10.key尽可能短;

    降低内存,减少哈希表的算法执行时间;

11.新版本的redis开启多线程(redis自身的多线程是主线程处理命令,其它几个线程处理IO);

12.不要存过大的数据;

    过大的数据存取和删除都会更为耗时;

13.使用pipline批量操作数据;

14.设置数据过期时间;

      设置过期时间,减少redis中的数据量,但要注意避免大量数据同时失效;

15.减少不必要的连接;

     能用连接池的情况下使用连接池;

性能分析方法:

1.慢操作日志:

CONFIG SET slowlog-log-slower-than 0 单位是微秒,若设置为0则相当于记录了所有的操作

CONFIG SET slowlog-max-len 10000000 最大慢日志长度

slowlog get 10 查看redis操作的执行耗时;

2.基准测试

redis-cli --intrinsic-latency 120      (120是测试时间)

基准测试要在系统无压力下进行,是为了排除硬件网络等本身就有较大的延迟,当执行延迟达到基准测试时间2倍及以上可以认为redis是变慢了;

记录一份checklist:

1.获取当前环境的基线性能

2.是否使用了慢查询? 

   用其它命令代替慢查询命令
3.是否对过期key设置了相同的过期时间?

4.是否使用了bigkey?

   采用异步删除

5.AOF的配置级别是什么?是否符合业务场景?

   避免IO影响性能,关于IO这块看是否可以使用SSD磁盘

6.Redis内存是否占用过大?使用swap了吗?

    如果使用了swap可能就需要考虑增加系统内存了

7.Redis运行环境中是否启用了大页机制?

   启用了则需要关闭,对持久化不友好,持久化是有了修改就需要大量复制

8.是否使用了主从集群?

   启用了主从集群需要控制数据量大小为2G-4G,避免主从复制带来大量的开销;

9.是否使用了多核心CPU?

   可以给Redis绑定物理核

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐