Redis
Nosql概述
在介绍Redis之前,首先先要介绍Nosql的概念。
互联网架构发展
在90年代的时候,计算机访问量一般不大,单个数据库足以应付,网页更多的是静态网页,动态交互性。于是出现了下面的架构
上述架构在数据存储的瓶颈有以下几点:
1.数据量的总大小 一个机器放不下2.数据的索引(B+ Tree)一个机器的内存放不下3.访问量(读写混合)一个实例不能承受
后来,随着访问量的上升,几乎大部分使用MySQL架构的网站在数据库上都开始出现了性能问题,web程序不再仅仅专注在功能上,同时也在追求性能。程序员们开始大量的使用缓存技术来缓解数据库的压力,优化数据库的结构和索引。开始比较流行的是通过文件缓存来缓解数据库压力,但是当访问量继续增大的时候,多台web机器通过文件缓存不能共享,大量的小文件缓存也带了了比较高的IO压力。在这个时候,Memcached就自然的成为一个非常时尚的技术产品。
Memcached作为一个独立的分布式的缓存服务器,为多个web服务器提供了一个共享的高性能缓存服务,在Memcached服务器上,又发展了根据hash算法来进行多台Memcached缓存服务的扩展,然后又出现了一致性hash来解决增加或减少缓存服务器导致重新hash带来的大量缓存失效的弊端
由于数据库的写入压力增加,Memcached只能缓解数据库的读取压力。读写集中在一个数据库上让数据库不堪重负,大部分网站开始使用主从复制技术来达到读写分离,以提高读写性能和读库的可扩展性。Mysql的master-slave模式成为这个时候的网站标配了。
在Memcached的高速缓存,MySQL的主从复制,读写分离的基础之上,这时MySQL主库的写压力开始出现瓶颈,而数据量的持续猛增,由于MyISAM使用表锁,在高并发下会出现严重的锁问题,大量的高并发MySQL应用开始使用InnoDB引擎代替MyISAM。
同时,开始流行使用分表分库来缓解写压力和数据增长的扩展问题。这个时候,分表分库成了一个热门技术,是面试的热门问题也是业界讨论的热门技术问题。也就在这个时候,MySQL推出了还不太稳定的表分区,这也给技术实力一般的公司带来了希望。虽然MySQL推出了MySQL Cluster集群,但性能也不能很好满足互联网的要求,只是在高可靠性上提供了非常大的保证。
MySQL数据库也经常存储一些大文本字段,导致数据库表非常的大,在做数据库恢复的时候就导致非常的慢,不容易快速恢复数据库。比如1000万4KB大小的文本就接近40GB的大小,如果能把这些数据从MySQL省去,MySQL将变得非常的小。关系数据库很强大,但是它并不能很好的应付所有的应用场景。MySQL的扩展性差(需要复杂的技术来实现),大数据下IO压力大,表结构更改困难,正是当前使用MySQL的开发人员面临的问题。
今天架构是下面这个样子:
为什么使用NoSQL ?
今天我们可以通过第三方平台(如:Google,Facebook等)可以很容易的访问和抓取数据。用户的个人信息,社交网络,地理位置,用户生成的数据和用户操作日志已经成倍的增加。我们如果要对这些用户数据进行挖掘,那SQL数据库已经不适合这些应用了, NoSQL数据库的发展也却能很好的处理这些大的数据。
Nosql是什么
NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题,包括超大规模数据的存储。
(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
Nosql能做什么
1.易扩展:NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。
2.大数据量高性能:NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。这得益于它的无关系性,数据库的结构简单。一般MySQL使用Query Cache,每次表的更新Cache就失效,是一种大粒度的Cache,在针对web2.0的交互频繁的应用,Cache性能不高。而NoSQL的Cache是记录级的,是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了
3.多样灵活的数据模型:NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦
4.传统RDBMS VS NOSQL:
RDBMS
-
高度组织化结构化数据
-
结构化查询语言(SQL)
-
数据和关系都存储在单独的表中。
-
数据操纵语言,数据定义语言
-
严格的一致性
-
基础事务
NoSQL
-
代表着不仅仅是SQL
-
没有声明性查询语言
-
没有预定义的模式-键 - 值对存储,列存储,文档存储,图形数据库
-
最终一致性,而非ACID属性
-
非结构化和不可预知的数据
-
CAP定理
-
高性能,高可用性和可伸缩性
Nosql数据模型简介
KV键值
Bson(类似Json)
列族:顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。
图
NoSQL数据库的四大分类
KV键值:新浪:BerkeleyDB+redis,美团:redis+tair,阿里、百度:memcache+redis
文档型数据库(bson格式比较多):CouchDB,MongoDB。MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
列存储数据库:Cassandra, HBase,分布式文件系统
图关系数据库:社交网络,推荐系统等。专注于构建关系图谱,Neo4J, InfoGrid。
分类 | 举例 | 应用场景 | 数据模型 | 优点 | 缺点 |
---|---|---|---|---|---|
键值(key-value) | Tokyo<br />Cabinet/Tyrant<br />Redis<br />Voldemort<br />Oracle BDB | 内容缓存,主要用于处理大量数据的高访问负载,也用于一些日志系统等等 | Key指向Value的键值对,通常用hash table来实现 | 查找速度快 | 数据无结构化,通常只当作字符串或者二进制数据 |
列存储数据库 | Cassandra<br />HBase<br />Riak | 分布式的文件系统 | 以列簇式存储,将同一列数据存在一起 | 查找速度快,可扩展性强,更容易进行分布式扩展 | 功能相对局限 |
文档型数据库 | CouchDB<br />Mongodb | Web应用(与Key-Value类似,value是结构化的,不同的是数据库能够了解Value的内容) | Key-Value对应的键值对,Value为结构化数据 | 数据结构要求不严格,表结构可变,不需要像关系型数据哭一样预先定义表结构 | 查询性能不高,而且缺乏统一的查询语法 |
图形数据库 | Neo4J<br />InfoGrid<br />Infinite<br />Graph | 社交网络,推荐系统等,专注于构建关系图谱 | 图结构 | 利用图结构相关算法。比如最短路径寻址,N度关系查找等 | 很多时候需要对整个图做计算才能得出需要的信息,而且这种结构不太好做分布式的集群方案 |
CAP+Base
关系型数据库遵循ACID规则
事务在英文中是transaction,和现实世界中的交易很类似,它有如下四个特性:
1、A (Atomicity) 原子性原子性很容易理解,也就是说事务里的所有操作要么全部做完,要么都不做,事务成功的条件是事务里的所有操作都成功,只要有一个操作失败,整个事务就失败,需要回滚。比如银行转账,从A账户转100元至B账户,分为两个步骤:1)从A账户取100元;2)存入100元至B账户。这两步要么一起完成,要么一起不完成,如果只完成第一步,第二步失败,钱会莫名其妙少了100元。
2、C (Consistency) 一致性一致性也比较容易理解,也就是说数据库要一直处于一致的状态,事务的运行不会改变数据库原本的一致性约束。
3、I (Isolation) 独立性所谓的独立性是指并发的事务之间不会互相影响,如果一个事务要访问的数据正在被另外一个事务修改,只要另外一个事务未提交,它所访问的数据就不受未提交事务的影响。比如现有有个交易是从A账户转100元至B账户,在这个交易还未完成的情况下,如果此时B查询自己的账户,是看不到新增加的100元的
4、D (Durability) 持久性持久性是指一旦事务提交后,它所做的修改将会永久的保存在数据库上,即使出现宕机也不会丢失。
CAP的含义
C:Consistency(强一致性)
A:Availability(可用性)
P:Partition tolerance(分区容错性)
CAP的的3进2
CAP理论就是说在分布式存储系统中,最多只能实现上面的两点。因此,根据 CAP 原理将 NoSQL 数据库分成了满足 CA 原则、满足 CP 原则和满足 AP 原则三 大类。而由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡,没有NoSQL系统能同时保证这三点。
-
CA - 单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大。传统Oracle数据库
-
CP - 满足一致性,分区容忍必的系统,通常性能不是特别高。 Redis、Mongodb
-
AP - 满足可用性,分区容忍性的系统,通常可能对一致性要求低一些。大多数网站架构的选择
注意:分布式架构的时候必须做出取舍。一致性和可用性之间取一个平衡。多余大多数web应用,其实并不需要强一致性。因此牺牲C换取P,这是目前分布式数据库产品的方向
一致性与可用性的决择
对于web2.0网站来说,关系数据库的很多主要特性却往往无用武之地
- 数据库事务一致性需求
很多web实时系统并不要求严格的数据库事务,对读一致性的要求很低, 有些场合对写一致性要求并不高。允许实现最终一致性。
- 数据库的写实时性和读实时性需求
对关系数据库来说,插入一条数据之后立刻查询,是肯定可以读出来这条数据的,但是对于很多web应用来说,并不要求这么高的实时性,比方说发一条消息之 后,过几秒乃至十几秒之后,我的订阅者才看到这条动态是完全可以接受的。
- 对复杂的SQL查询,特别是多表关联查询的需求
任何大数据量的web系统,都非常忌讳多个大表的关联查询,以及复杂的数据分析类型的报表查询,特别是SNS类型的网站,从需求以及产品设计角 度,就避免了这种情况的产生。往往更多的只是单表的主键查询,以及单表的简单条件分页查询,SQL的功能被极大的弱化了。
BASE的含义
BASE就是为了解决关系数据库强一致性引起的问题而引起的可用性降低而提出的解决方案。
BASE其实是下面三个术语的缩写: 基本可用(Basically Available) 软状态(Soft state) 最终一致(Eventually consistent)
它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上改观。为什么这么说呢,缘由就在于大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,要想获得这些指标,我们必须采用另外一种方式来完成,这里BASE就是解决这个问题的办法
分布式系统
分布式系统(distributed system)由多台计算机和通信的软件组件通过计算机网络连接(本地网络或广域网)组成。分布式系统是建立在网络之上的软件系统。正是因为软件的特性,所以分布式系统具有高度的内聚性和透明性。因此,网络和分布式系统之间的区别更多的在于高层软件(特别是操作系统),而不是硬件。分布式系统可以应用在在不同的平台上如:Pc、工作站、局域网和广域网上等。
简单来讲:1分布式:不同的多台服务器上面部署不同的服务模块(工程),他们之间通过Rpc/Rmi之间通信和调用,对外提供服务和组内协作。
2集群:不同的多台服务器上面部署相同的服务模块,通过分布式调度软件进行统一的调度,对外提供服务和访问。
Redis
是什么——概念
Redis:REmote DIctionary Server(远程字典服务器)是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器
Redis 与其他 key - value 缓存产品有以下三个特点:
-
Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
-
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
-
Redis支持数据的备份,即master-slave模式的数据备份
能做啥
-
内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
-
取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面
-
模拟类似于HttpSession这种需要设定过期时间的功能
-
发布、订阅消息系统
-
定时器、计数器
安装——基于Linux
-
下载获得redis-XXX.tar.gz后将它放入我们的Linux目录/opt
-
/opt目录下,解压命令:tar -zxvf redis-XXX.tar.gz
-
进入目录:cd redis-XXX
-
在redis-XXX目录下执行make命令
-
如果make完成后继续执行make install
-
查看默认安装目录:usr/local/bin
-
修改redis.conf文件将里面的daemonize no 改成 yes,让服务在后台启动
-
将默认的redis.conf拷贝到自己定义好的一个路径下,比如/myconf
-
/usr/local/bin目录下运行redis-server,运行拷贝出存放了自定义conf文件目录下的redis.conf文件
-
启动redis客户端:redis-cli -p 6379
-
测试连通性:输入ping 返回 PONG 测试成功
-
单实例关闭:redis-cli shutdown;多实例关闭,指定端口关闭:redis-cli -p 6379 shutdown
杂项知识
-
Redis 是单进程
-
默认16个数据库,初始默认使用零号库(Redis索引都是从零开始),统一密码管理,16个库都是同样密码,要么都OK要么一个也连接不上
-
select命令切换数据库 select 2切换到标号为2的库
-
dbsize查看当前数据库的key的数量
-
flushdb:清空当前库
-
Flushall:清空全部库
Redis数据类型
Redis支持5大数据类型:
-
string(字符串)
string 是Redis的基本类型,一个key对应一个Value,String是二进制安全的,及时说Redis的String可以包含任何数据,比如jpg图片或者序列化的对象,一个Redis中字符串value最多是512M
-
hash(哈希,类似java里的Map)
Redis hash是一个键值对集合,是一个string类型的field和value的映射表,特别适合用于存储对象,类似于Java里面的
Map<String,Object>
-
list(列表)
Redis List 是简单的字符串列表,按照插入的顺序排序,可以添加一个元素到列表的头部或者尾部,底层其实是一个链表
-
set(集合)
是String类型的无序集合,通过HashTable实现
-
zset(sorted set:有序集合)
和set一样也是String类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数score却可以重复。
每种数据类型相关命令请参考http://redisdoc.com/本文不再赘述
Redis配置文件
配置文件放在解压目录中redis.conf
-
开头:配置文件开头定义了一些基本度量单位,只支持bytes不支持bit,对大小写不敏感
-
INCLUDE:Redis可以作为总闸,包含一些其他的配置文件
-
NETWORK:配置一些网络参数,如设置有效监听的客户端连接地址,监听端口等
-
tcp-backlog:backlog其实是一个链接队列,backlog队列总和=未完成三次握手队列+已完成三次握手队列
在高并发的环境下你需要一个高backlog值来避免慢客户端链接问题。Linux内核会将这个值减小到/proc/sys/net/core/somaxconn的值,所以需要确保提高somaxconn和tcp_max_syn_backlog两个值来达到目标效果
-
tcp-keepalive:间隔多长时间进行keepalive检测,从Redis3.2.1之后默认值为300此前为60
(不同版本Redis配置文件结构不一样,老版本没有此分类,原来放在GENERAL里面)
-
-
GENERAL:
-
daemonize 后台启动
-
loglevel 设置日志级别,级别越高日志越多越详细
-
logfile 日志文件
-
databases 默认Redis数据库数量——16个
-
-
SNAPSHOTTING:RDB的持久化配置将Redis数据库保存在磁盘上,详见本文持久化部分
-
REPLICATION:设置主从复制
-
SECURITY:访问密码的查看、设置和取消。默认Redis是没有密码的,因为它相信安装环境Linux是安全的
-
LIMITS:对Redis进行一些限制,如最大连接客户端数量,使用内存等
-
APPEND ONLY MODE:Redis AOF持久化的一些配置,详见本文持久化部分
Redis持久化
Redis 有两种持久化技术RDB和AOF
http://redisdoc.com/topic/persistence.html 推荐参考官方文档
RDB(Redis DataBase)
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是Snapshot,它恢复时是将快照文件直接读到内存里。
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
Fork:fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。
RDB 保存的是dump.rdb文件
如何触发RDB快照
-
Save命令:save时只管保存,其它不管,全部阻塞
-
bgsave命令:Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间
-
flushall命令:也会产生dump.rdb文件,但里面是空的,无意义
RDB默认配置触发是:
-
1分钟改了1万次
-
5分钟改了10次
-
15分钟改了1次
如何恢复
将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可
如何停止
停止RDB保存规则的方法:redis-cli config set save ""
AOF(Append Only File)
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
Aof保存的是appendonly.aof文件
如何启动AOF
修改默认的appendonly no,改为yes
AOF损坏修复
redis-check-aof --fix进行修复
rewrite
AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof
-
重写原理
AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似
-
触发机制
Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
总结
RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储
AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大
只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.
同时开启两种持久化方式:
-
在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
-
RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢?作者建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),快速重启,而且不会有AOF可能潜在的bug,留着作为一个万一的手段。
性能建议:
因为RDB文件只用做后备用途,建议只在Slave上持久化RDB文件,
如果使用AOF,好处是最恶劣的情况下只会丢失不超过2秒的数据,代价是持续的IO,AOF 的Rewrite过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的,应尽量减少rewrite的频率,默认重写基础大小是64M太小,可以根据需求设置GB级别的写入大小。
如果不使用AOF,仅适用Master-Slave Replication实现高可用也可以,能省掉一大笔的IO,代价是如果M和S同时挂掉,会丢失十几分钟的数据,启动脚本只要比较两个RDB的文件载入较新的。新浪微博选用这种架构
Redis的事务
事务流程
-
开启:以MULTI开始一个事务
-
入队:将多个命令入队到事务中,接到这些命令并不会立即执行,而是放到等待执行的事务队列里面
-
执行:由EXEC命令触发事务
事务执行分类
-
正常执行
-
放弃事务:DISCARD放弃事务执行
-
全体连坐:有一个错误全部失败
-
冤头债主:谁有错谁不执行,不影响其他的语句
-
watch监控
watch监控
-
乐观锁:
乐观锁(Optimistic Lock), 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制判断是否修改。乐观锁适用于多读的应用类型,这样可以提高吞吐量,乐观锁策略:提交版本必须大于记录当前版本才能执行更新
-
悲观锁:
悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁
Watch指令,类似乐观锁,事务提交时,如果Key的值已被别的客户端改变,比如某个list已被别的客户端push/pop过了,整个事务队列都不会被执行
通过WATCH命令在事务执行之前监控了多个Keys,倘若在WATCH之后有任何Key的值发生了变化,EXEC命令执行的事务都将被放弃,同时返回Nullmulti-bulk应答以通知调用者事务执行失败
Redis事务特性
-
单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
-
没有隔离级别的概念:队列中的命令没有提交之前都不会实际的被执行,因为事务提交前任何指令都不会被实际执行,也就不存在”事务内的查询要看到事务里的更新,在事务外查询不能看到”这个让人万分头痛的问题
-
不保证原子性:redis同一个事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚
Redis的发布和订阅
进程间的一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
一次订阅多个:SUBSCRIBE c1 c2 c3(可以使用通配符,例如SUBSCRIBE news*)
消息发布 :PUBLISH c2 helloworld
一般企业中发布消息中间件不会使用Redis去做,了解即可
Redis的复制
也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slave以读为主
可以做什么:读写分离,容灾备份
使用
遵循配从(库)不配主(库)的原则
-
从库配置:slaveof 主库IP 主库端口
每次与master断开之后,都需要重新连接,除非你配置进redis.conf文件(使用info replication 可以查看当先信息)
需要修改的配置:
拷贝多个redis.conf文件开启daemonize yespid文件名字指定端口log文件名字dump.rdb名字
-
常用配置结构
-
一主二仆:一个Master两个Slave,主机挂掉之后,剩下的机器还是slave状态,主机复活之后维持原来的主机地位,从机挂掉,除非是写过配置文件,否则不会恢复从机的身份。
-
薪火相传:上一个Slave可以是下一个slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master,可以有效减轻master的写压力
-
反客为主:SLAVEOF no one,使当前数据库停止与其他数据库的同步,转成主数据库
-
Redis复制原理
slave启动成功连接到master后会发送一个sync命令。Master接到命令启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步
全量复制:而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中。增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步但是只要是重新连接master,一次完全同步(全量复制)将被自动执行
哨兵模式
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
使用
-
新建sentinel.conf文件
-
填写内容: sentinel monitor 被监控数据库名字(自己起名字) 127.0.0.1 6379 1(1表示主机挂掉后salve投票看让谁接替成为主机,得票数多少后成为主机)
-
启动 redis-sentinel sentinel.conf 哨兵开始监控主机,主机挂掉选取主机,原主机重新启动之后将会变成Slave
一组sentinel能同时监控多个Master
复制的缺点
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
问题
-
Redis和Memcache区别对比?如何选择这两个技术?
区别:
1) Redis和Memcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等。
2)Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储。
3)虚拟内存--Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘
4)过期策略--memcache在set时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10
5)分布式--设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从
6)存储数据安全--memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化)
7)灾难恢复--memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复
8)Redis支持数据的备份,即master-slave模式的数据备份。
选型:
若是简单的存取key-value这样的数据用memcache好一些
若是要支持数据持久化,多数据类型(如集合、散列之类的),用列表类型做队列之类的高级应用,就用redis
-
Redis的持久化机制是什么?各自的优缺点?
redis提供两种持久化机制RDB和AOF机制。
1)RDB持久化方式:
是指用数据集快照的方式记录redis数据库的所有键值对。
优点:
1.只有一个文件dump.rdb,方便持久化。
2.容灾性好,一个文件可以保存到安全的磁盘。
3.性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。
4.相对于数据集大时,比AOF的启动效率更高。
缺点:
1.数据安全性低。
2)AOF持久化方式:
是指所有的命令行记录以redis命令请求协议的格式保存为aof文件。
优点:
1.数据安全,aof持久化可以配置appendfsync属性,有always,每进行一次命令操作就记录到aof文件中一次。
2.通过append模式写文件,即使中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题。
3.AOF机制的rewrite模式。
缺点:
1.文件会比RDB形式的文件大。
2.数据集大的时候,比rdb启动效率低。