大家好,我是IT修真院西安分院第三期学员,一枚正直纯洁善良的JAVA程序员。
今天给大家分享一下,修真院官网JAVA任务六,深度思考中的知识点——MemCache和Redis的区别
一、背景介绍
Memcache和Redis
Memcache :是 danga.com 的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。
Redis:2008年,意大利的一家创业公司Merzia推出了一款基于MySQL的网站实时统计系统 LLOOGG,然而没过多久该公司的创始人 Salvatore Sanfilippo 便对MySQL 的性能感到失望,于是他决定亲自为 LLOOGG 量身定做一个 数据库,并并于 2009 年开发完成,这个数据库就是Redis。
Redis 和 Memcache 都是基于内存的数据存储系统。Memcached是高性能分布式内存缓存服务;Redis是一个开源的key-value存储系统。 与Memcached类似,Redis将大部分数据存储在内存中,支持的数据类型包括:字符串、哈希 表、链表、等数据类型的相关操作。
MemCache:
MemCache是一个自由、源码开放、高性能、分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高了网站访问的速度。
二、知识剖析
MemCache和Redis的区别
(1)数据类型支持不同
(2)内存管理机制不同
(3)数据持久化支持
(4)集群管理的不同
2.1.数据类型支持不同
(1) Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用缓存其他东西,例如图片、视频等等
(2)Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储
2.2内存管理机制不同
MemCache: memcache使用slab allocator机制来内存管理。
slab allocator原理:先将内存划分为多个slab class仓库,每个仓库切分成不同尺寸的小块chunk。需要存储内容时候,判断内容大小,为其选择合理的仓库;
Redis:底层实现通过对malloc/free进行封装来实现,通过存储数据的size,来申请一段连续的内存空间;
Redis通过定义一个数组来记录所有的内存分配情况,这个数组的长度为ZMALLOC_MAX_ALLOC_STAT。数组的每一个元素代表当前程序所分配的内存块的个数,且内存块的大小为该元素的下标。在源码中,这个数组为zmalloc_allocations。zmalloc_allocations[16]代表已经分配的长度为16bytes的内存块的个数。
2.3数据存储及持久化
memcached不支持内存数据的持久化操作,所有的数据都以in-memory的形式存储。
redis支持持久化操作。redis提供了两种不同的持久化方法来讲数据存储到硬盘里面,一种是快照(snapshotting),它可以将存在于某一时刻的所有数据都写入硬盘里面。另一种方法叫只追加文件(append-only file, AOF),它会在执行写命令时,将被执行的写命令复制到硬盘里面。
2.4集群管理不同
Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。
相较于Memcached只能采用客户端实现分布式存储,Redis更偏向于在服务器端构建分布式存储。Redis本身提供集群服务的。
三、常见问题
Memcache和Redis集群对比简介
四、解决方案
Memcache和Redis集群对比简介
Memcache:
Memcached本身并不支持分布式,因此只能在客户端通过像一致性哈希这样的分布式算法来实现Memcached的分布式存储。
当客户端向Memcached集群发送数据之前,首先会通过内置的分布式算法计算出该条数据的目标节点,然后数据会直接发送到该节点上存储。但客户端查询数据时,同样要计算出查询数据所在的节点,然后直接向该节点发送查询请求以获取数据。
Redis官方集群方案 Redis Cluster
Redis Cluster是一种服务器Sharding技术,3.0版本开始正式提供。对客户端来说,整个cluster被看做是一个整体,客户端可以连接任意一个node进行操作,就像操作单一Redis实例一样,当客户端操作的key没有分配到该node上时,就像操作单一Redis实例一样,当客户端操作的key没有分配到该node上时,Redis会返回转向指令,指向正确的node。
总体来说,
MemCache在客户端通过hash算法,根据key把数据发往不同的memcached服务器端;
Redis将所有的数据发往Redis服务器端的集群,由Redis集群自动存储到相应的节点;
五、编码实战
六、扩展思考
redis的持久化方法
redis提供了两种不同的持久化方法来讲数据存储到硬盘里面,一种是快照(snapshotting),它可以将存在于某一时刻的所有数据都写入硬盘里面。另一种方法叫只追加文件(append-only file, AOF),它会在执行写命令时,将被执行的写命令复制到硬盘里面。
快照(snapshotting):通过save命令,以下为默认
save 900 1 //对redis数据只进行1次修改,间隔900s写入硬盘
save 300 10 //对redis数据进行10次修改,间隔300s写入硬盘
save 60 10000
最后生成rdb文件,写在硬盘上;
只追加文件(append-only file, AOF):默认不开启。
appendonly no
以下为默认设置:
# appendfsync always
appendfsync everysec
# appendfsync no
七、参考文献
https://blog.youkuaiyun.com/u011489043/article/details/78922390
https://www.cnblogs.com/_popc/p/5968683.html
8.更多讨论
1、MemCache和Redis性能对比
由于 Redis 只使用单核,而 Memcached 可以使用多核,所以平均每一个核上 Redis 在存储小数据时比 Memcached 性能更高。而在 100k 以上的数据中,Memcached 性能要高于 Redis,虽然 Redis 最近也在存储大数据的性能上进行优化,但是比起 Memcached,还是稍有逊色
Memcache多线程,Redis单线程,处理数据较小没有太大区别;单线程模型会严重影响整体吞吐量,CPU计算过程中,整个IO调度都是被阻塞的。
2、MemCache内存分配
Memcached在启动时通过-m参数指定最大使用内存,但是这个不会一启动就占用完,而是逐步分配给各slab的。如果一个新的数据要被存放,首先选择一个合适的slab,然后查看该slab是否还有空闲的chunk,如果有则直接存放进去;如果没有则要进行申请,slab申请内存时以page为单位,无论大小为多少,都会有1M大小的page被分配给该slab(该page不会被回收或者重新分配,永远都属于该slab)。申请到page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk的数组,再从这个chunk数组中选择一个用于存储数据。若没有空闲的page的时候,则会对改slab进行LRU,而不是对整个memcache进行LRU。
3、什么叫MemCached不支持分布式,Redis支持集群服务?
都是针对服务器端的,Redis3.0正式支持集群服务,通过配置文件中的:
#是否使用集群----yes
cluster-enabled yes
感谢观看,如有出错,恳请指正