性能优化之Redis优化
Redis是一个我们常用的高性能组件,在使用Redis的场景下通常我们会对性能较高要求,Redis通常情况能满足我们的要求,但某些情况下我们还会对Redis进行进一步的优化;谈优化前我们首先要对Redis要有一个全局的认识,Redis是单线程,Redis作为KV数据库包括访问框架,操作模块,索引模块,存储模块;Redis的访问方式包括UNIX套接字和TCP;操作模块和数据结构相关,包括string
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绑定物理核
更多推荐



所有评论(0)