Netty+Redis开发高并发应用的一些思考(二)

上一篇《Netty+Redis开发高并发应用的一些思考(一)》提及到Redis的优化,最近一个月的开发调测和部署又有了一些新的想法:

  1. Redis尽量放在本地,减少网络IO时间;对相应时间要求高的,尽量不要用云服务商提供的Redis服务,别人的服务再好,读写速度也比不上本地的。

  2. Redis放在本地,在服务器集群环境下就有数据同步的问题。之前尝试过很多方案,Redis自己的Ruby集群、Twitter的Twemproxy等等,都不适合我们的应用场景——这些集群更多地考虑可用性和数据分片、扩容性,但对一些多键操作支持很差,而且也有各种缺陷(如使用Redis自带的Ruby集群,至少3主3从,可以建好3主3从的集群之后,手动移动Slot到同一台主机,删除其他主机,变成1主3从,但这个集群一旦关闭就很难启动起来。)。

    寻寻觅觅,最后发现Redis自带的原始主从复制最适合我们,集群的不同的服务器之间只需要一台主机作为Redis主机,其他服务器的Redis服务设置slaveof属性,作为其从机。
    此外,可以将从机的只读属性设为no,但往Slave写入的数据会在下一次同步的时候被Master的数据所覆盖——这样做的目的在于写入一些临时缓存变量。

  3. 只有一台服务器的情况下,如果是多核服务器(16核及以上),由于Redis是单线程的,只能利用一个CPU内核,只开一个Redis服务实例可能压力很大(可以从CPU占用看出来),此时也可以使用上面提到的主从复制功能,在同一台服务器上开启多个Redis实例分担查询压力,提高并发性能。

  4. Linux系统中,可以使用

    taskset -cp [CPU核心号码,从0开始] [要执行的命令]
    

    来指定要执行的命令在哪些CPU内核上运行,在多核服务器上,可以合理利用此命令来分配CPU资源,如指定多个Redis和Netty分别运行在多个内核上,并指定哪个Netty服务使用哪个Redis服务(需要自己编写Netty服务,读取配置文件,使用不同端口的Redis服务),避免资源浪费和拥挤。

  5. Redis指令的优化及自定义计算缓存。在Redis官网文档和很多微博都对SLOWLOG命令有介绍,在此不细述细节。利用SLOWLOG我们可以找到执行比较慢的命令,从而进行优化。比如我们的系统在测试一段时间之后,通过SLOWLOG命令得知耗时较长的都是某一步并集操作,而这个操作与请求的具体内容有关,所以后来我为之设了一个缓存,通过EXPIRE命令设置缓存的生命周期(随着时间推移这个计算的结果是不一样的,需要更新),每次新的请求在计算这一步时,先查询缓存中是否存在计算结果,存在的话直接读取,不存在(全新的计算或旧的已过期)则重新计算并放入运算缓存。