Redis
Redis是一个开源的内存型数据库,存储key-value pair;使用ANSI C语言实现。项目中曾经用Redis作为缓存。据说新浪微博就大量使用Redis。
一、内存型数据库
Redis是内存型数据库,我们知道内存读取速度优于磁盘,这也是redis高性能的原因。内存资源昂贵,为了用有限的内存存储更多数据同时不牺牲性能,Redis采用了虚拟内存,把不经常访问的数据放到磁盘。Redis同时实现了持久化,通过两种方式:
1)默认方式:快照,用dump.rdb文件存储数据;可配置redis在N秒内超过M个key被修改时触发快照:通过fork创建子进程,父进程继续处理client请求,子进程写临时快照文件,写完后替换原有快照文件,子进程退出。这里的快照是全量数据快照,而非增量。如果redis意外down掉,则丢失最后一次快照后的所有修改。
2)Append-only file:解决数据丢失问题;每收到一个写命令就追加写命令到append only.aof文件,redis重启后执行文件中存储的写命令来恢复数据。文件存储写命令而不是终极数据快照,伴随命令增多文件会膨胀;redis解决该问题的方式是采用类似快照的方式将内存数据以写命令形式保存到临时文件,用于替换文件。
二、分布式架构
Redis的分布式架构(多台机器(nodes)同时存储数据和状态,彼此交换消息来保持数据一致)意味着Redis具有更强的可扩展性。
采用主从同步方式:1. slave启动/重启后和master建立连接,发送命令到master; 2. master收到命令后启动后台进程,把数据快照保存成文件并发送给slave;3. slave把文件中数据加载到内存;4. 后续master会把收到的写命令转发给slave保持数据同步。如果master同时收到多个slave的连接请求,只启动一个线程写文件并发送给所有slave。
三、丰富的数据类型与操作
支持数据类型包括基本类型和集合类型,提供基于数据类型的原子操作;如String用于存储json字符串,图片编码字符串;Hash用于存储对象;List:子元素为string类型的双向链表,可以用作栈/队列;set/sorted set。
操作如set及其扩展setne/setex/mset等;get及其扩展mget/getset;delete/exists;list的push/pop等。需要时可以查看《Redis实战》。
四、Redis的事务
Redis能保证一个client发起的一系列命令连续执行,中间不插入其他client的命令。redis是单线程处理所有client请求;一般情况下,redis接到client请求会立即处理并返回结果;但如果client发送multi命令,就会进入事务上下文,把后续命令存放到队列,收到exec命令后顺序执行。
五、对比关系型数据库
1. 海量数据存储场景:RDBMS通过对数据库切割将整个数据库部署到一个集群上 ;而Redis的key-value扩展性更强,增加机器就可以了。
2. 云存储即构建一个大型存储平台给别人用:作为包租婆并不知道别人的数据是什么样的;这种场景下key-value是唯一选择;如Amazon simpleDB和google的googleAppEngine
3. 高并发:对于 RDBMS,一般几百个并发的查询就可以让它很吃 力了,而一个 Key-Value Store,可以很轻松的支持上千的并发查询
4. 性能:RDBMS数据在磁盘,redis数据在内存,读写速度快。
六、对比memcache
1. Redis支持更多的数据类型;2. Redis支持持久化;
七、Spring Cache中使用redis的配置
# Redis服务器地址:spring.redis.host=192.168.1.1
# database:spring.redis.database = 1
# Redis服务器连接端口 使用默认端口6379可以省略配置:spring.redis.port=6379
# Redis服务器连接密码(默认为空):spring.redis.password=1234
# 连接池最大连接数(如果配置<=0,则没有限制 ):spring.redis.jedis.pool.max-active=8