Redis数据结构及使用场景

一、在Rredis 中一共有 5 种数据结构,都是key - value 形式存储

String-------------字符串
Hash--------------字典
List ----------------列表
Set-----------------集合
Sorted Set-------有序集合redis



二、五种结构各自的使用场景:


1. String——字符串

        String 数据结构是简单的 key-value 类型,value 不只能够是 String,也能够是数字(当数字类型用 Long 能够表示的时候 encoding 就是整型,其余都存储在 sdshdr 当作字符串)。使用 String 类型,能够彻底实现目前 Memcached 的功能,而且效率更高。还能够享受 Redis 的定时持久化(能够选择 RDB 模式或者 AOF 模式),操做日志及Replication 等功能。除了提供与 Memcached 同样的 get、set、incr、decr 等操做外,Redis还提供了下面一些操做:数据库

代码以下:后端

1.LEN niushuai:O(1)获取字符串长度
2.APPEND niushuai redis:往字符串 append 内容,并且采用智能分配内存(每次 2 倍)
3.设置和获取字符串的某一段内容
4.设置及获取字符串的某一位(bit)
5.批量设置一系列字符串的内容
6.原子计数器
7.GETSET 命令的妙用,请于清空旧值的同时设置一个新值,配合原子计数器使用缓存


2. Hash——字典

在 Memcached 中,咱们常常将一些结构化的信息打包成 hashmap,在客户端序列化后存储为一个字符串的值(通常是 JSON 格式),好比用户的昵称、年龄、性别、积分等。这时候在须要修改其中某一项时,一般须要将字符串(JSON)取出来,而后进行反序列化,修改某一项的值,再序列化成字符串(JSON)存储回去。简单修改一个属性就干这么多事情,消耗一定是很大的,也不适用于一些可能并发操做的场合(好比两个并发的操做都须要修改积分)。而 Redis 的 Hash 结构可使你像在数据库中 Update 一个属性同样只修改某一项属性值。
存储、读取、修改用户属性服务器


3. List——列表

List 说白了就是链表(redis 使用双端链表实现的 List),相信学过数据结构知识的人都应该能理解其结构。使用 List 结构,咱们能够轻松地实现最新消息排行等功能(好比新浪微博的 TimeLine )。List 的另外一个应用就是消息队列,能够利用 List 的 *PUSH 操做,将任务存在 List 中,而后工做线程再用 POP 操做将任务取出进行执行。Redis 还提供了操做 List 中某一段元素的 API,你能够直接查询,删除 List 中某一段的元素。
1.微博 TimeLine
2.消息队列网络


4. Set——集合

Set 就是一个集合,集合的概念就是一堆不重复值的组合。利用 Redis 提供的 Set 数据结构,能够存储一些集合性的数据。好比在微博应用中,能够将一个用户全部的关注人存在一个集合中,将其全部粉丝存在一个集合。由于 Redis 很是人性化的为集合提供了求交集、并集、差集等操做,那么就能够很是方便的实现如共同关注、共同喜爱、二度好友等功能,对上面的全部集合操做,你还可使用不一样的命令选择将结果返回给客户端仍是存集到一个新的集合中。
1.共同好友、二度好友
2.利用惟一性,能够统计访问网站的全部独立 IP
3.好友推荐的时候,根据 tag 求交集,大于某个 threshold 就能够推荐session


5. Sorted Set——有序集合

和 Set相比,Sorted Set 是将 Set 中的元素增长了一个权重参数 score,使得集合中的元素可以按 score 进行有序排列,好比一个存储全班同窗成绩的 Sorted Sets,其集合 value能够是同窗的学号,而 score 就能够是其考试得分,这样在数据插入集合的时候,就已经进行了自然的排序。另外还能够用 Sorted Sets 来作带权重的队列,好比普通消息的 score为 1,重要消息的 score 为 2,而后工做线程能够选择按 score 的倒序来获取工做任务。让重要的任务优先执行。数据结构

1.带有权重的元素,好比一个游戏的用户得分排行榜
2.比较复杂的数据结构,通常用到的场景不算太多并发


3、redis 其余功能使用场景

1. 订阅-发布系统


Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在 Redis 中,你能够设定对某一个 key 值进行消息发布及消息订阅,当一个 key 值上进行了消息发布后,全部订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用做实时消息系统,好比普通的即时聊天,群聊等功能。app


2. 事务——Transactions


谁说 NoSQL 都不支持事务,虽然 Redis 的 Transactions 提供的并非严格的 ACID 的事务(好比一串用 EXEC 提交执行的命令,在执行中服务器宕机,那么会有一部分命令执行了,剩下的没执行),可是这个 Transactions 仍是提供了基本的命令打包执行的功能(在服务器不出问题的状况下,能够保证一连串的命令是顺序在一块儿执行的,中间有会有其它客户端命令插进来执行)。Redis 还提供了一个 Watch 功能,你能够对一个 key 进行 Watch,而后再执行 Transactions,在这过程当中,若是这个Watched 的值进行了修改,那么这个
Transactions 会发现并拒绝执行。

1. 使用 redis 有哪些好处?
(1) 速度快,由于数据存在内存中,相似于 HashMap,HashMap 的优点就是查找和操做的时间复杂度都是 O(1)
(2) 支持丰富数据类型,支持 string,list,set,sorted set,hash
(3) 支持事务,操做都是原子性,所谓的原子性就是对数据的更改要么所有执行,要么所有不执行
(4) 丰富的特性:可用于缓存,消息,按 key 设置过时时间,过时后将会自动删除
2. redis 相比 memcached 有哪些优点?
(1) memcached 全部的值均是简单的字符串,redis 做为其替代者,支持更为丰富的数据类型
(2) redis 的速度比 memcached 快不少
(3) redis 能够持久化其数据


3. redis 常见性能问题和解决方案:

(1) Master 最好不要作任何持久化工做,如 RDB 内存快照和 AOF 日志文件
(2) 若是数据比较重要,某个 Slave 开启 AOF 备份数据,策略设置为每秒同步一次
(3) 为了主从复制的速度和链接的稳定性,Master 和 Slave 最好在同一个局域网内
(4) 尽可能避免在压力很大的主库上增长从库
(5) 主从复制不要用图状结构,用单向链表结构更为稳定,即:Master <- Slave1 <- Slave2<- Slave3... 这样的结构方便解决单点故障问题,实现 Slave 对 Master 的替换。若是 Master 挂了,能够马上启用 Slave1 作 Master,其余不变。

4. mySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中的数据都是热点数据相关知识:redis 内存数据集大小上升到必定大小的时候,就会施行数据淘汰策略。

redis 提供 6 种数据淘汰策略:

voltile-lru:从已设置过时时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰
volatile-ttl:从已设置过时时间的数据集(server.db[i].expires)中挑选将要过时的数据淘汰
volatile-random:从已设置过时时间的数据集(server.db[i].expires)中任意选择数据淘汰
allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰
allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰
no-enviction(驱逐):禁止驱逐数据


4、Memcache 与 Redis 的区别都有哪些?

1)、存储方式
Memecache 把数据所有存在内存之中,断电后会挂掉,数据不能超过内存大小。
Redis 有部份存在硬盘上,这样能保证数据的持久性。

2)、数据类型
Memcache 对数据类型支持相对简单。
Redis 有五种的数据类型。

3)、底层模型
它们之间底层实现方式以及与客户端之间通讯的应用协议不同。Redis 直接本身构建了 VM 机制 ,由于通常的系统调用系统函数的话,会浪费必定的时间去移动和请求。

4)、value大小
redis 最大能够达到 1GB,而 memcache 只有 1MB

5、Redis 常见的性能问题都有哪些?如何解决?


1).Master 写内存快照,save 命令调度 rdbSave 函数,会阻塞主线程的工做,当快照比较大时对性能影响是很是大的,会间断性暂停服务,因此 Master 最好不要写内存快照。
2).Master AOF 持久化,若是不重写 AOF 文件,这个持久化方式对性能的影响是最小的,可是 AOF 文件会不断增大,AOF 文件过大会影响 Master 重启的恢复速度。Master 最好不要作任何持久化工做,包括内存快照和 AOF 日志文件,特别是不要启用内存快照作持久化,若是数据比较关键,某个 Slave 开启 AOF 备份数据,策略为每秒同步一次。
3).Master 调用 BGREWRITEAOF 重写 AOF 文件,AOF 在重写的时候会占大量
的 CPU 和内存资源,致使服务 load 太高,出现短暂服务暂停现象。
4). Redis 主从复制的性能问题,为了主从复制的速度和链接的稳定性,Slave
和 Master 最好在同一个局域网内
7, redis 最适合的场景
Redis 最适合全部数据 in-momory 的场景,虽然 Redis 也提供持久化功能,但实际更多的是一个 disk-backed 的功能,跟传统意义上的持久化有比较大的差异,那么可能你们就会有疑问,彷佛 Redis 更像一个增强版的 Memcached,那么什么时候使用 Memcached,什么时候使用 Redis 呢?
若是简单地比较 Redis 与 Memcached 的区别,大多数都会获得如下观点:
1 、Redis 不只仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,
hash 等数据结构的存储。
2 、Redis 支持数据的备份,即 master-slave 模式的数据备份。
3 、Redis 支持数据的持久化,能够将内存中的数据保持在磁盘中,重启的时候能够再次加载进行使用。

(1)、会话缓存(Session Cache)最经常使用的一种使用 Redis 的情景是会话缓存(session cache)。用 Redis 缓存会话比其余存储(如 Memcached)的优点在于:Redis 提供持久化。当维护一个不是严格要求一致性的缓存时,若是用户的购物车信息所有丢失,大部分人都会不高兴的,如今,他们还会这样吗?
幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用 Redis 来缓存会话的文档。甚至广为人知的商业平台 Magento 也提供 Redis 的插件。

(2)、全页缓存(FPC)除基本的会话 token 以外,Redis 还提供很简便的 FPC 平台。回到一致性问题,即便重启了 Redis 实例,由于有磁盘的持久化,用户也不会看到页面加载速度的降低,这是一个极大改进,相似 PHP 本地 FPC。再次以 Magento 为例,Magento 提供一个插件来使用 Redis 做为全页缓存后端。此外,对 WordPress 的用户来讲,Pantheon 有一个很是好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。

(3)、队列Reids 在内存存储引擎领域的一大优势是提供 list 和 set 操做,这使得 Redis 能做为一个很好的消息队列平台来使用。Redis 做为队列使用的操做,就相似于本地程序语言(如 Python)对 list 的 push/pop 操做。 若是你快速的在 Google 中搜索“Redis queues”,你立刻就能找到大量的开源项目,这些项目的目的就是利用 Redis 建立很是好的后端工具,以知足各类队列需求。例如,Celery 有一个后台就是使用 Redis 做为 broker,你能够从这里去查看。 (4),排行榜/计数器Redis 在内存中对数字进行递增或递减的操做实现的很是好。集合(Set)和有序集合(Sorted Set)也使得咱们在执行这些操做的时候变的很是简单,Redis 只是正好提供了这两种数据结构。因此,咱们要从排序集合中获取到排名最靠前的 10 个 用户–咱们称之为“user_scores”,咱们只须要像下面同样执行便可:固然,这是假定你是根据你用户的分数作递增的排序。若是你想返回用户及用户的分数,你须要这样执行:ZRANGE user_scores 0 10 WITHSCORESAgora Games 就是一个很好的例子,用 Ruby 实现的,它的排行榜就是使用 Redis来存储数据的,你能够在这里看到。 (5)、发布/订阅最后(但确定不是最不重要的)是 Redis 的发布/订阅功能。发布/订阅的使用场景确实很是多。我已看见人们在社交网络链接中使用,还可做为基于发布/订阅的脚本触发器,甚至用 Redis 的发布/订阅功能来创建聊天系统!(不,这是真的,你能够去核实)。 Redis 提供的全部特性中,我感受这个是喜欢的人最少的一个,虽然它为用户提供若是此多功能。