12:Redis的性能优化

1.使用管道(Pipeline)

Redis的底层通讯协议对管道提供了支持,通过管道,可以一次性发送多条命令给Redis,在执行完后一次性将结果取回。使用管道,可以减少客户端和Redis的通信次数,降低网络延时,从而提供性能。Redis的管道功能在命令行中没有,但Redis是支持管道的,而且在各个语言版的client中都有相应的实现。

2.精简键名和键值

3.合理设计存储的数据结构和数据关系,尽量减少数据冗余

4. 尽量使用mset来赋值,比set效率高一个数量级;类似的还有lpush、zadd等都可以一次输入多个指令

5.如果可能,尽量使用Lua脚本来辅助获取或操作数据

6. 尽量使用hash结构来存储对象将一个对象存储在hash类型中会占用更少的内存,并且可以更方便的存取整个对象,省内存的原因是新建一个hash对象时开始是用zipmap来存储的。

7.使用hash结构时,应尽量保证每个key下面的的数目不超过限制(默认值为64),否则插入效率下降十分明显,同样,内存开销也会显著增加

配置使用ziplist以优化list

1.如果list的元素个数小于配置值list-max-ziplist-entries且元素值字符串的长度小于配置值list-max-ziplist-value,则可以编码成ziplist类型存储,否则采用 Dict 来存储,Dict实际是Hash Table的一种实现。

2.配置使用intset以优化set

3.当set集合中的元素为整数且元素个数小于配置set-max-intset-entries值时,使用intset数据结构存储,否则转化为Dict结构

4. 配置使用ziplist以优化sorted set当sorted set的元素个数及元素大小小于一定限制时,它是用ziplist来存储。这个限制的配置如下:zset-max-ziplist-entries、zset-max-ziplist-value

5. 配置使用zipmap以优化hash当entry数量没有超过hash-max-ziplist-entries指定的限制,并且值的最大长度没有超过hash-max-ziplist-value指定的限制时,会用zipmap来编码。

注意:HashMap的优势就是查找和操作的时间复杂度都是O(1)的,而放弃Hash采用一维存储则是O(n)的时间复杂度,如果成员数量很少,则影响不大,否则会严重影响性能,所以要权衡好些个值的设置,在时间成本和空间成本上进行权衡

一定要设置maxmemory

设置Redis使用的最大物理内存,也就是使用了这么多物理内存后就开始拒绝后续的写入请求,该参数能保护Redis不会因为使用了过多的物理内存而严重影响性能甚至崩溃。

 对排序的优化

1:尽量让要排序的Key存放在一个Server上如果采用客户端分片,那么具体决定哪个key存在哪个服务器上,是由client端采用一定算法来决定的,因此可以通过只对key的部分进行hash。

比如:client如果发现key中包含{},那么只对key中{}包含的内容进行hash。如果采用服务端分片,也可以通过控制key的有效部分,来让这些数据分配到同一个插槽中。

2:尽量减少Sort的集合大小如果要排序的集合非常大, 会消耗很长时间,Redis单线程的,长时间的排序操作会阻塞其它client的请求。解决办法是通过主从复制,将数据复制到多个slave上,然后只在slave上做排序操作,并尽可能的对排序结果缓存

1.考虑采用复制+RDB的方式

1.使用复制机制来实现高可用,数据采用RDB的方式进行持久化备份,建议只在Slave上持久化RDB文件,而且只要在一个相对较长的时间备份一次就够了,比如只保留save 900 1这条规则,大致就是15分钟保存一次。

这样的方式避免了AOF带来的持续的IO,也避免AOF Rewrite最后将rewrite过程中产生的新数据写到新文件所造成的阻塞。代价是如果Master/Slave同时倒掉,可能会丢失15分钟的数据。

2.考虑在一台服务器启动多个Redis实例

由于Redis使用单线程,为了提高CPU利用率,可以在同一台服务器上启动多个Redis实例,但这可能会带来严重的IO争用,除非Redis不需要持久化,或者有某种方式保证多个实例不会在同一个时间重写AOF。

你可能感兴趣的:(12:Redis的性能优化)