redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
在redis中并不是所有的数据都是一致存储在内存中。这个是与memcache相比一个最大的区别。redis只会缓存所有的key信息,如果redis发现内存的使用量超过了某一阀值,将触发swap操作,redis根据swappabilty = age *log(size_in_memory) 计算出那些key对应的value需要swap到磁盘。然后将这个key对应的value持久化到磁盘中,同时在内存中清除。这种特性使得redis能够保持超过其机器本身内存大小的数据。
从redis中读取数据的时候,如果读取的key值不在内存中,那就需要从swap文件中加载相应的数据,然后返回给请求方。这里就存在一个i/o线程池的问题。在默认情况下,redis会出现阻塞i,及完成所有的swap文件加载之后才会相应。这种策略在客户端的数量小,进行批量操作的时候比较合适。但是如果将redis应用在一个大型的网站应用程序中,肯定是无法满足高并发的情况。
redis 与Memcache 不同点
1. 网络i/o模型
memcache是多线程,非阻塞io复用的网络模型,分为监听主线程还有worker子线程监听线程监听网络连接,接受请求之后,将连接描述自pipe传递给worker线程,进行读写io,网络层使用libevent封装的事件库,多线程模型可以发挥多核作用。
redis使用单线程的io复用模型。
2.内存管理方面
memcache 是使用预分配的内存池的方式。
redis采用的是线程申请内存的方式来存储数据。redis根据存储的命令参数会把过期的时间的数据单独放在一起,并把它们称之为临时数据。非临时数据是永远不会被剔除的,即使物理内存不够。swap也不会剔除任何非临时数据(但是会尝试剔除临时数据),这点上面redis更加适合做存储而不是cache。
3.数据一致性问题
memcache提供了cas命令,可以保证多个并发访问操作同一份数据的一致性问题。redis没有提供cas命令,并不能保证这一点。不过redis提供了事务的功能,可以保证一连串命令的原子性,中间不会被任何操作打断。
4.储存方式及其他方面
memcache只支持简单的key-value存储,不知处枚举,持久化和复制的功能
redis除了支持键值对格式的数据存储之外,还支持list,set,sorts,hash等数据结构。