Redis 与 memcache的区别

Redis 与 memcache的区别

1. 数据结构

Redis提供了更多的数据结构,当需要这些复杂的数据结构时,会选择Redis,因为memcache只是提供了简单的k-v

  • String:String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操作时会转成数值型进行计算,此时redisObject的encoding字段为int。

    适用场景:普通的key-value可以归为此类

  • List列表:Redis列表是简单的字符串列表,Redis list的实现为一个双向链表,即可以支持反向查找和遍历。

    适用场景:比如twitter的关注列表、粉丝列表

  • Hash:Redis Hash对应Value内部实际就是一个HashMap

    适用场景:

    1. 假设有多个用户及对应的用户信息,可以用来存储以用户ID为key,将用户信息序列化为比如json格式做为value进行保存。get的时候只用传key 和 HashMap中的key,然后把hashMap中的value取出来。

    2. 在Memcached中,我们经常将一些结构化的信息打包成HashMap,在客户端序列化后存储为一个字符串的值,比如用户的昵称、年龄、性别、积分等,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。

    3. 一种方式将用户ID作为查找key,把其他信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增加了序列化/反序列化的开销,并且在需要修改其中一项信息时,需要把整个对象取回,并且修改操作需要对并发进行保护,引入CAS等复杂问题。

     

  • Set:值不重复的列表。

    适用场景:需要不重复的列表时

  • Sorted Set:一个有序集合的每个成员带有分数,用于进行排序。Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是所有的成员,排序依据是HashMap里存的score,使用跳跃表的结构可以获得比较高的查找效率,并且在实现上比较简单。

2. 持久化

memcache无法满足持久化的需求。但是也千万不要把Redis当做数据库用,因为:

  1. Redis的定期快照不能保证数据不丢失:当更新一个值后,还未来得及AOF并且异步复制到其他机器时,此时这台机器宕机,这个更新的值会丢失

  2. redis的AOF会降低效率,并且不能支持太大的数据量

    • always:同步持久化,每次发生数据变更会被立即记录到磁盘,性能较差数据完整性较好(但也有可能丢失最后一次的数据)

    • everysec:默认,异步操作,每秒记录,如果一秒内机器出现问题,则会有数据丢失

    • No:不使用

如果只是用作缓存,开启持久化有什么利弊?

优点:Redis挂了再重启,内存里能够快速恢复热数据,不会瞬时将压力压在数据库上,没有一个cache预热的过程。

缺点:在挂了的过程中,如果数据库中有数据的修改,可能导致Redis重启后,数据库与Redis的数据不一致。(使用缓存本来就是需要能容忍数据暂时不一致的情况,因此,只读场景,或者允许一些不一致的业务场景,可以尝试开启redis的固化功能。)

3. 高可用

Redis支持集群功能,可以实现主动复制,读写分离。而memcache需要进行二次开发,例如:客户端的双写双读,或者服务端的集群同步。

缓存场景,其实就是要可以容忍cache Miss,如果缓存挂了,很多时候可以通过DB读取数据。但是在即时通讯业务中,业务的在线状态,就需要高可用。

 

什么时候倾向于memcache?

纯KV,数据量非常大,并发量非常大的业务,使用memcache或许更适合。

内存分配:memcache更快一些

  1. memcache使用预分配内存池的方式管理内存,能够省去内存分配时间。但是数据量不能超过预分配内存大小

  2. Redis则是临时申请空间,可能导致碎片。虚拟内存,redis当物理内存用完时,可以就用一些很久没用到的value交换到磁盘。

网络模型:memcache更快一些

  1. Redis和memcache都是使用非阻塞的IO复用模型,但是Redis还提供了一些排序、聚合功能,复杂的cpu计算,会阻塞整个IO调度。

线程模型:memcache更快一些

  1. memcache使用多线程,主线程监听,worker子线程接受请求,执行读写,这个过程中,可能存在锁冲突。memcache使用CAS来进行解决并发问题。

  2. Redis使用单线程,虽无锁冲突,但难以利用多核的特性提升整体吞吐量。但是保证了数据按顺序提交,提供了事务的功能,可以保证一串命令的原子性

注:部分摘自沈剑的公众号

你可能感兴趣的:(Nosql)