Java server数据之(4):Redis鸟瞰
Redis简介
Redis是NoSQL数据库中的一种,属于key-value键值对这一个子类别。 它常被称作是一款数据结构服务器(data structure server)。 Redis中的数据结构都是存在于内存中的,所以Rdis也可以被称为是内存型数据库, 顾名思义就是将数据放在内存中直接操作的数据库。Redis既可以用来作为key-value db, 也可以用来作为cache,据说还可以用作消息中间件。Redis的名称含义:REmote DIctionary Server.
运行环境与安装
Lniux下:Redis的代码遵循ANSI-C编写,可以在所有POSIX系统(如Linux, *BSD, Mac OS X, Solaris等)上安装运行。而且Redis并不依赖任何非标准库,也没有编译参数必需添加。redis的安装出奇的简单,不像Linux世界中的某些东西,编译阶段就能让人完全绝望。
数据结构服务器
redis 的作者antirez曾称其为一个数据结构服务器(data structures server),这是一个非常准确的表述,redis的所有功能就是将数据以其固有的几种结构保存,并提供给用户操作这几种结构的接口。我们可以想象我们在各种语言中的那些固有数据类型及其操作。还需要注意的是, 一旦把数据放在Redis中, 我们就可以使用不同的语言访问这些数据。
Redis数据类型
Redis可以把key映射成多种不同类型的value。Redis与其他结构化存储系统的主要不同就在于Redis不仅支持string,而且还支持抽象数据类型。
redis目前提供四种数据类型:string,list,set及zset(sorted set)和Hash。
- string是最简单的类型,你可以理解成与Memcached一模一个的类型,一个key对应一个value,其上支持的操作与Memcached的操作类似。但它的功能更丰富。
- list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。
- set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。
- zset是set的一个升级版本,他在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解了有两列的mysql表,一列存value,一列存顺序。操作中key理解为zset的名字。
- Hash数据类型允许用户用Redis存储对象类型,Hash数据类型的一个重要优点是,当你存储的数据对象只有很少几个key值时,数据存储的内存消耗会很小.更多关于Hash数据类型的说明请见: http://code.google.com/p/redis/wiki/Hashes
思考问题: Redis与Java提供的数据结构有什么不同呢?
Redis vs Memcached
1 速度:
很多开发者都认为Redis不可能比Memcached快,Memcached完全基于内存,而Redis具有持久化保存特性,即使是异步的,Redis也不可能比Memcached快。但是测试结果基本是Redis占绝对优势。
2 使用场景:
memcached偏向cache,redis更多扮演数据库的角色,支持更丰富的数据类型,单从性能上比,不太具有可比性,不会有数量级的差异. 两者也可并存,在数据库(redis)前端布置cache(memcached)也是一种节省资源的方式。Memcached是全内存Cache,仅此功能,数据持久化等相关都需要自己制作。Redis上面已经说了,更多扮演的是数据库的功能,自带数据持久化。如果只是简单的key value并且没有持久化cache需求,可以考虑采用mc。但是,现在越来越多的内存cache也越来越多地使用Redis。
Redis持久化
Redis对持久化的支持主要是通过RDB和AOF文件来进行持久化的。其中RDB
持久化是在指定的时间间隔内生成数据集的时间点快照。而AOF
持久化记录的是服务器执行的所有写操作命令,在服务器启动的时候,通过重新执行这些命令来还原数据集的。AOF文件中的命令全部以Redis协议的格式来保存,新的命令会被追加到文件的末尾。Redis还可以在后台对AOF文件进行重写,使得AOF文件的体积不会超出保存数据集状态所需要的实际大小。
Redis可以同时使用AOF持久化和RDB持久化,在这种情况下,Redis重启之后,他会优先使用AOF文件来还原数据集,因为AOF文件保存的数据集通常要比RDB文件中保存的数据集更加的完整。当然也可以关闭持久化功能,让数据仅仅在服务器运行的时候存在。
1 snap方式优缺点:
RDB 是一个非常紧凑(compact)的文件,它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。因此RDB 非常适用于灾难恢复(disaster recovery)。
但是,我们可以很明显的看到,RDB有他的不足,就是一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的,从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了。在某些业务下,这是可以忍受的,我们也推荐这些业务使用RDB的方式进行持久化,因为开启RDB的代价并不高。但是对于另外一些对数据安全性要求极高的应用,无法容忍数据丢失的应用,RDB就无能为力了,所以Redis引入了另一个重要的持久化机制:AOF日志。
2 aof日志的全称是append only file,从名字上我们就能看出来,它是一个追加写入的日志文件。与一般数据库的binlog不同的是,AOF文件是可识别的纯文本,它的内容就是一个个的Redis标准命令。
总结 :RDB和AOF操作都是顺序IO操作,性能都很高。而同时在通过RDB文件或者AOF日志进行数据库恢复的时候,也是顺序的读取数据加载到内存中。所以也不会造成磁盘的随机读。
(这里需要特别注意,在阿里御膳房的电面中,被问到磁盘顺序读与随机读的性能区别问题。)
作为数据库, Redis与MySQL的比较
这些持久化的数据有什么用,当然是用于重启后的数据恢复。Redis是一个内存数据库,无论是RDB还是AOF,都只是其保证数据恢复的措施。所以Redis在利用RDB和AOF进行恢复的时候,都会读取RDB或AOF文件,重新加载到内存中。相对于MySQL等数据库的启动时间来说,会长很多,因为MySQL本来是不需要将数据加载到内存中的。
但是相对来说,MySQL启动后提供服务时,其被访问的热数据也会慢慢加载到内存中,通常我们称之为预热,而在预热完成前,其性能都不会太高。而Redis的好处是一次性将数据加载到内存中,一次性预热。这样只要Redis启动完成,那么其提供服务的速度都是非常快的。
面试题实例:
小米问题:
redis 如何解决冲突? 是像HashMap那样再Hash吗??
答案是不是,redis主要通过一致性Hash来解决冲突。
阿里面试问题:
redis如何实现分布式缓存? 一致性Hash??
redis的索引??
redis如何分表??
partation
range partitioning往往是不能令人满意的,因为它不如其他partition方案的效率高。它的替代方案可以是hash partitioning. hash partitioning的一个优势是一致性Hash。
参考文献:
http://stackoverflow.com/questions/10558465/memcached-vs-redis
https://en.wikipedia.org/wiki/Redis
http://www.cnblogs.com/dandandeyoushangnan/p/4657177.html
http://try.redis.io/
张善友:http://www.cnblogs.com/shanyou/archive/2012/01/28/2330451.html
http://labs.alcacoop.it/doku.php?id=articles:redis_land
持久化:http://www.cnblogs.com/rollenholt/p/3874390.html
Redis集群:
http://www.cnblogs.com/huangxincheng/p/5615037.html
https://en.wikipedia.org/wiki/NoSQL
https://en.wikipedia.org/wiki/Redis
partition:
http://redis.io/topics/partitioning