精英联盟总队 缓存框架Redis、Memcached技术选型,「微服务」

使用缓存的目的和问题缓存的目的是加快数据的读取数据 , 有效减少核心应用、数据库的压力 。 但是缓存的使用也同时牺牲了其他方面的优势 , 比如数据的强一致性 。
因此 , 我们在使用缓存提高读取性能的同时 , 一定会失去一定的一致性 。 在某些场景下对读取缓存的一致性要求并不很高 , 因此可以牺牲一定的一致性来换取高性能 。
缓存框架现在业界面主要流的分布式缓存框架首选Redis或者Memcached 。 两者都具有足够高的性能和稳定性 , 但是又存在一些差异 。
具体使用哪个缓存框架作为业务上的使用框架呢?
如果有了解过二者差异的同学 , 应该大致的知道二者之前的一些差异:
支持的数据类Memcached仅支持简单的key-value数据类型 , Redis额外可以支持list、set、zset、hash等数据结构 。 数据的备份Memcached不支持数据待久化 , 重启数据丢失 。 Redis支持master-slave模式的数据备份 , 同时支持数据待久化 , 重启可以恢复数据 。 等等...从上面看起来 , Redis看起来比Memcached香得多了 。 但是实际是这样吗?
我们具体对比一下二者之间的差异 。
Redis与Memcahced的差异对比网络IO模型MemcachedMemcached是多线程 , 非阻塞IO复用的网络模型 , 分为监听主线程和worker子线程 , 监听线程监听网络连接 , 接受请求后 , 将连接描述字pipe传递给worker线程 , 进行读写IO , 网络层使用libevent封装的事件库 , 多线程模型可以发挥多核作用 , 但是引入了cachecoherency和锁的问题 , 比如:Memcached最常用的stats命令 , 实际Memcached所有操作都要对这个全局变量加锁 , 进行技术等工作 , 带来了性能损耗 。
Redis6.0版本支持了多线程 。
因为读写网络的read/write系统调用在Redis执行期间占用了大部分CPU时间 , 如果把网络读写做成多线程的方式对性能会有很大提升 。 Redis6.0将writeside即回复客户端这部分去掉了主线程和IO线程之间的互斥锁 , 采用busyloop的形式来等待io线程工作结束 , 这部分能够有50%的性能提升 。
多线程IO的读(请求)和写(响应)在实现流程是一样的 , 只是执行读还是写操作的差异 。 同时这些IO线程在同一时刻全部是读或者写 , 不会部分读或部分写的情况 。
加入多线程IO之后 , 整体的读流程如下:
主线程负责接收建连请求 , 读事件到来(收到请求)则放到一个全局等待读处理队列主线程处理完读事件之后 , 通过RR(RoundRobin)将这些连接分配给这些IO线程 , 然后主线程忙等待(spinlock的效果)状态IO线程将请求数据读取并解析完成(这里只是读数据和解析并不执行)主线程执行所有命令并清空整个请求等待读处理队列(执行部分串行)上面的这个过程是完全无锁的 , 因为在IO线程处理的时主线程会等待全部的IO线程完成 , 所以不会出现datarace的场景 。


推荐阅读