Redis
什么是redis?
- (Remote Dictionary Server ),即远程字典服务
- 是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API
- 是一种NoSQL数据库;
- 从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助
redis有哪些特点?
- 开源
- 包含多种数据结构
- 支持网络、基于内存、可选持久性的健值对存储
- 基于内存性能高
- C/S通讯模型
- 单进程单线程模型
- 操作具有原子性
- 高并发读写(可达到11万/秒)
- 支持lua脚本
备注:github,twitter,微博,stack overflow,阿里,百度,美团,搜狐都有在用redis
redis的基本架构?
- redis是单进程单线程
redis的工作原理?
redis 有哪些数据类型?
- Redis提供的数据类型主要分为5种自有类型和一种自定义类型,这5种自有类型包括:String类型、哈希类型、列表类型、集合类型和顺序集合类型
- String
它是一个二进制安全的字符串,意味着它不仅能够存储字符串、还能存储图片、视频等多种类型, 最大长度支持512M
GET/MGET
SET/SETEX/MSET/MSETNX
INCR/DECR
GETSET
DEL
- 哈希类型
该类型是由field和关联的value组成的map。其中,field和value都是字符串类型的。
Hash的操作命令如下:
HGET/HMGET/HGETALL
HSET/HMSET/HSETNX
HEXISTS/HLEN
HKEYS/HDEL
HVALS
- 列表类型
该类型是一个插入顺序排序的字符串元素集合, 基于双链表实现。
List的操作命令如下:
LPUSH/LPUSHX/LPOP/RPUSH/RPUSHX/RPOP/LINSERT/LSET
LINDEX/LRANGE
LLEN/LTRIM
- 集合类型:
Set类型是一种无顺序集合, 它和List类型最大的区别是:集合中的元素没有顺序, 且元素是唯一的。
Set类型的底层是通过哈希表实现的,其操作命令为:
SADD/SPOP/SMOVE/SCARD
SINTER/SDIFF/SDIFFSTORE/SUNION
Set类型主要应用于:在某些场景,如社交场景中,通过交集、并集和差集运算,通过Set类型可以非常方便地查找共同好友、共同关注和共同偏好等社交关系。
- 顺序集合类型:
ZSet是一种有序集合类型,每个元素都会关联一个double类型的分数权值,通过这个权值来为集合中的成员进行从小到大的排序。与Set类型一样,其底层也是通过哈希表实现的。
ZSet命令:
ZADD/ZPOP/ZMOVE/ZCARD/ZCOUNT
ZINTER/ZDIFF/ZDIFFSTORE/ZUNION
redis 的高可用方案?
redis的数据备份方案?
redis使用场景?
- 缓存系统(“热点”数据:高频读、低频写)、计数器、消息队列系统、排行榜、社交网络和实时系统
1.会话缓存(Session Cache)
最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的。
2.队列
Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。
3.全页缓存
大型互联网公司都会使用Redis作为缓存存储数据,提升页面相应速度。即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降。
4.排行榜/计数器
Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单。
redis与其它NoSql相比有哪些优缺点?
-
Memcache:这是一个和Redis非常相似的数据库,但是它的数据类型没有Redis丰富。Memcache由LiveJournal的Brad Fitzpatrick开发,作为一套分布式的高速缓存系统,被许多网站使用以提升网站的访问速度,对于一些大型的、需要频繁访问数据库的网站访问速度的提升效果十分显著。
-
Apache Cassandra:(社区内一般简称为C*)这是一套开源分布式NoSQL数据库系统。它最初由Facebook开发,用于储存收件箱等简单格式数据,集Google BigTable的数据模型与Amazon Dynamo的完全分布式架构于一身。Facebook于2008将 Cassandra 开源,由于其良好的可扩展性和性能,被 Apple、Comcast、Instagram、Spotify、eBay、Rackspace、Netflix等知名网站所采用,成为了一种流行的分布式结构化数据存储方案。
-
MongoDB:是一个基于分布式文件存储、面向文档的NoSQL数据库,由C++编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系型数据库的,它支持的数据结构非常松散,是一种类似json的BSON格式。
Redis的RDB和AOF ?
- RDB是将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复
- 配置文件中的配置样例:
dbfilename dump.rdb
dir ./
- RDB:自动的持久化数据存储到dump.rdb后。实际只要重启redis服务即可完成
-
RDB:通过设置SAVE来完成持久化策略:
-
AOF是将执行过的指令记录下来,数据恢复时按照从前到后的顺序再将指令执行一遍,实现数据恢复
- AOF默认关闭,开启方法,修改配置文件redis.conf:appendonly yes,默认是每秒将写操作日志追加到AOF文件中
- 针对AOF文件越来越大的问题,可以对AOF文件进行重写,命令如下:
redis-cli -h ip -p port bgrewriteaof ./redis-cli -h 127.0.0.1 -p 6379 bgrewriteaof
- 触发AOF持久化的条件:根据配置文件触发,可以是每次执行触发,可以是每秒触发,可以不同步
- 运行一段时间后,aof的文件会特别大,redis会对aof进行重写
- 触发机制:当AOF文件大小是上次rewrite后大小的一倍且文件大于64M(可以配置)时触发
- 重写的原理:Redis 会fork出一条新进程,读取内存中的数据,并重新写到一个临时文件中。并没有读取旧文件(你都那么大了,我还去读你??? o(゚Д゚)っ傻啊!)。最后替换旧的aof文件
- 重启redis服务,前提是配置文件必须设置了appendonly yes,然后会从appendfile的文件加载文件。反之是从RDB中加载数据的。
-
cluster集群的配置,使用的存储方式就必须是AOF方式
-
RDB
优点:
1 适合大规模的数据恢复。
2 如果业务对数据完整性和一致性要求不高,RDB是很好的选择。
缺点:
1 数据的完整性和一致性不高,因为RDB可能在最后一次备份时宕机了。
2 备份时占用内存,因为Redis 在备份时会独立创建一个子进程,将数据写入到一个临时文件(此时内存中的数据是原来的两倍哦),最后再将临时文件替换之前的备份文件。
所以Redis 的持久化和数据的恢复要选择在夜深人静的时候执行是比较合理的
- AOF优点:数据的完整性和一致性更高
- AOF缺点:因为AOF记录的内容多,文件会越来越大,数据恢复也会越来越慢
Redis 持久化之RDB和AOF REDIS持久化之RDB和AOF的区别
如何做高可用集群?
- redis有三种常见的高可用方案
* 主从复制
* sentinel
* cluster
- 主从复制
一个master,至少一个slave
可以主从分离:主节点写入,从节点读
master故障后,可以将从节点提升为master
简单,但不能自动故障转移
- sentinel
* 提供sentinel监控集群,对redis进行监控,Sentinel不断的检查master和slave是否正常的运行
* 当sentinel发现master宕机,可以自动将slave提升为master
* 哨兵作为Redis客户端发现的权威来源:客户端连接到哨兵请求当前可靠的master的地址。如果发生故障,哨兵将报告新地址
* 构建sentinel集群:一般为3+,保证sentinel本身的高可用
* 虽然sentinel集群中各个sentinel都互相连接彼此来检查对方的可用性以及互相发送消息。但是你不用在任何一个sentinel配置任何其它的sentinel的节点。因为sentinel利用了master的发布/订阅机制去自动发现其它也监控了统一master的sentinel节点
* 通过向名为__sentinel__:hello的管道中发送消息来实现
* 每个sentinel通过向每个master和slave的发布/订阅频道__sentinel__:hello每秒发送一次消息,来宣布它的存在
* 每个sentinel也订阅了每个master和slave的频道__sentinel__:hello的内容,来发现未知的sentinel,当检测到了新的sentinel,则将其加入到自身维护的master监控列表中
* 每个sentinel发送的消息中也包含了其当前维护的最新的master配置。如果某个sentinel发现自己的配置版本低于接收到的配置版本,则会用新的配置更新自己的master配置
* 在为一个master添加一个新的sentinel前,sentinel总是检查是否已经有sentinel与新的sentinel的进程号或者是地址是一样的。如果是那样,这个sentinel将会被删除,而把新的sentinel添加上去
* redis sentinel集群的配置的一致性模型为最终一致性,集群中每个sentinel最终都会采用最高版本的配置
* snetinel的状态会被持久化地写入sentinel的配置文件中。每次当收到一个新的配置时,或者新创建一个配置时,配置会被持久化到硬盘中,并带上配置的版本戳。这意味着,可以安全的停止和重启sentinel进程
* 移除一个Sentinel实例会相对麻烦一些,因为Sentinel不会忘记已经感知到的Sentinel实例,所以最好按照下列步骤来处理:
停止将要移除的sentinel进程。
给其余的sentinel进程发送SENTINEL RESET *命令来重置状态,忘记将要移除的sentinel,每个进程之间间隔30秒。
确保所有sentinel对于当前存货的sentinel数量达成一致,可以通过SENTINEL MASTER 命令来观察,或者查看配置文件
* 当个sentinel认为某个master宕机,则可以认为是主观宕机
* 通过 SENTINEL is-master-down-by-addr 命令互相交流,当有多于quorum个sentinel认为master宕机,则认为是客观宕机
* 当master被判定为客观下线以后,监视这个服务器的各个Sentinel会进行协商,选举出一个领头的Sentinel,并由领头Sentinel对下线主服务器进行故障转移。
* 每经过一次选举,无论选举成功还是失败,每隔sentinel实例的配置纪元都会自增1,每个新的纪元中,任何一个sentinel都有可能成为领头Sentinel
* 通过一定的vote算法,从剩下的slave从服务器节点中,选一台提升为Master服务器节点,然后自动修改相关配置,并开启故障转移
* Sentinel 机制可以解决master和slave角色的自动切换问题,但单个 Master 的性能瓶颈问题无法解决,类似于MySQL中的MHA功能
sentinel的三个定时:
1. 每10秒每个sentinel对master和slave执行info:发现slave节点,确认主从关系
2. 每2秒每个sentinel通过master节点的channel交换信息(pub/sub):通过sentinel__:hello频道交互,交互对节点的“看法”和自身信息
3. 每1秒每个sentinel对其他sentinel和redis执行ping:心跳检测,节点失败的依据
- cluster
Redis Sentinel文档 Redis Sentinel 实现原理详解 Redis Sentinel 工作原理详解
redis如何设置权限,如何设置数据库?
memcache与redis的区别
RDB与AOF的区别
为什么RDB要fork子进程而不是线程
- 一句话:保证写入到RDB的数据时准确的
- fork子进程,子进程完全复制了父进程的数据,子进程的操作和父进程没关系,可以保证写入RDB时就是该时刻的数据
- 用线程有可能会导致写入的数据不是创建线程时的数据,导致数据的不一致
- 如果是单机版本的redis,没有问题
- 但是如果是集群或者主从,主从数据同步依赖RDB,会导致数据的不一致 知乎参考