什么是Redis?
Redis是一个基于内存的高性能key-value数据库(Key-value数据库是一种以键值对存储数据的一种数据库)
Redis有什么特点
从本质上来说是一个key-value内存数据库,整个数据库统统加载在内存上进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存,是目前最快的key-value DB
Redis出色之处不仅仅在于性能,Redis最大的魅力在于能够存储多种的数据结构,并且单的value最大限制是1GB,因此Redis可以用来实现很多有用的功能,比方说用他的List来做双向链表,实现一个轻量级的消息队列服务,用他的Set做高性能的tag系统等等。
当然有优点肯定也有缺点,主要的缺点就是受到物理内存的限制,不能作为海量数据的高性能读写,所以一般来说,Redi适合的场景主要局限在较小的数据量高性能操作和运算上。
Redis是单进程单线程的,利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销
Redis支持的数据类型
1.strings(字符串)
a)如果只使用redis中的字符串类型,且不使用redis的持久化功能,那么,redis就和memcache非常非常的像了;
b)在遇到数值操作时,会自动转换过为字符串,如写入数字1,读出来将是字符串1;
c)本身具有原子性的指令:incr、decr和Memecached中increment、decrement类似;
d)应用场景:常规计数-微博数,粉丝数;
2.lists(列表)
a)lists数据类型的实现不是数组而是通过链表这种数据结构实现;
b)使用Lists结构,我们可以轻松地实现最新消息排行等功能。Lists的另一个应用就是消息队列,可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行;
c)每个子元素都是String类型的双向链表,可以通过push和pop操作从列表的头部或者尾部添加或者删除元素,这样List即可以作为栈,也可以作为队列;
3.sets(无序集合)
a)所谓集合就是一堆不重复值的组合,并且是没有顺序的;
b)在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
4.sorted sets(有序集合)
a)和Sets相比,Sorted Sets增加了一个权重参数score,使得集合中的元素能够按score进行有序排列;
b)比如一个存储全班同学成绩的Sorted Sets,其集合value可以是同学的学号,而score就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。可以用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。
c)应用场景:在线游戏的排行榜,根据得分你通常想要:
i.列出前100名高分选手
ii.列出某用户当前的全球排名
5.hashes(哈希)
a)在Memcached中,我们经常将一些结构化的信息打包成hashmap,在客户端序列化后存储为一个字符串的值,比如用户的昵称、年龄、性别、积分等,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。
b)应用场景:存储部分变更数据,如用户信息,session共享;
分布式
Redis支持主从模式,Master会将数据同步到slave,而slave不会将数据同步到Master。Slave启动时会连接Master来同步数据
这是一个典型的分布式读写分离模型,我们可以利用master来插入数据,slave来提供检索服务,这样可以有效的减少单个机器的并发访问数量。
使用Redis的好处
1、速度快,因为数据是存储在内存中的,类似于HashMap的优势就是查找和操作的时间复杂度都是O(1)
2、支持丰富的数据类型,支持String,list,set,sorted set,hash
3、支持事务,操作都是原子性的
4、丰富的特性,可用于缓存消息,按key设置过期时间,过期后自动删除
注意事项
1、Master最好不要做持久化工作,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,因为AOF文件会不断增大,过大的话会影响Master的重启速度。
2、如果数据比较重要,某个Slave开启AOF备份数据,策略最好每一秒同步一次
3、为了主从复制的速度和连接的稳定性,Master和Slave最好在同一个局域网内
4、尽量避免在压力很大的主库上增加从库
5、主从复制不要用图状结构,用单向链表更为稳定,即Master<-Slave1<-Slave2<-Slave3…
如何解决Redis的并发竞争问题
Redis为单进程单线程模式,采用队列模式将并发访问变为串行访问。Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争,但是在Jedis客户端对Redis进行并发访问时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成。对此有2种解决方法:
1.客户端角度,为保证每个客户端间正常有序与Redis进行通信,对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized。
2.服务器角度,利用setnx实现锁。
注:对于第一种,需要应用程序自己处理资源的同步,可以使用的方法比较通俗,可以使用synchronized也可以使用lock;第二种需要用到Redis的setnx命令,但是需要注意一些问题。
Redis持久化的几种方式
1、快照(snapshots)
2、AOF
3、虚拟内存方式
Redis最适合的场景
(1)、会话缓存(Session Cache)
(2)、全页缓存(FPC)
(3)、队列
(4),排行榜/计数器
(5)、发布/订阅