主要学的三个数据库
- MySQL(关系型) 多用于冷数据
- MongoDB(介于关系型与非关系型之间) 基于分布式文件存储的数据库
- Redis(非关系型数据库) 多用于常改变,类型多样的数据。分布式 内存 数据库
一、相关概念
NoSQL简介:
泛指 非关系型数据库 ,为了解决大规模数据集合多重数据种类,包括大规模数据存储。这些类型的数据存储不需要固定的模式,无需多余的操作就可以横向扩展。
NoSQL特点:
- 易扩展:去掉关系型数据库的关系型特性,数据之间无关系,因此非常容易扩展。
- 大数据量高性能:
- 多样灵活的数据类型:键值对形式存储。
关系型与非关系型数据库对比:
- RDBMS(Relational Database Management System):
- 高度组织化结构化数据
- 结构化查询语句
- 数据和关系都存储在单独的表中
- 数据操纵语言,数据定义语言
- 严格一致性
- NoSQL
- 不仅仅是SQL
- 没有声名性查询语言
- 没有预定义模式
- 键值对的存储,列存储、文档存储、图形数据库
- 最终一致性,非ACID属性
- 非结构化和不可预知的数据
- CAP定理
- 高性能、高可用性和可伸缩性
NoSQL实质:
KV(键值对) + Cache(缓存) + Persistence(持久性)
3V 3高:
- 3V :
- Volume(海量)
- Variety(多样)
- Velocity(实时)
- 3高:
- 高并发
- 高可扩(横向扩展)
- 高性能
NoSQL的数据模型(聚合模型):
- KV键值 :Redis
- Bson(Binary Json):MongoDB
- 列族:Hbase
- 图形:不是去放图形的,是存放关系,如社交网络,广告推荐,用于构建关系图谱。暂时用的少。
数据库的CAP+BASE
传统:ACID(分别查一下什么意思)
NoSQL:CAP (Consistency Availability Partition tolerance)强一致性+可用性+分区容错性
注意: CAP只能三选二,最多只能较好的满足两个,但是P又是必须满足的,如今网站多为AP
BASE:(Basically Available Soft state Eventually consistent)基本可用+ 软状态 + 最终一致。
分布式+集群:
- 分布式:多态服务器上部署不同的服务模块,它们之间进行Rcp/Rmi之间通讯和调用,对外提供服务和组内协作。
- 集群:多台服务器上部署相同的服务模块,通过分布式软件调度对外提供服务和访问,即实现负载均衡。
二、Redis
概念:
REmote DIctionary Server(远程字典服务)
特点:
开源、免费、C编写、遵守BSD协议。高性能KV分布式存储数据库,支持数据持久化、还支持list、set、hash等,支持数据备份,单线程工作 。分布式的内存数据库。
用途:
数据持久化、获取最新N个数据、模拟HttpSession这种需要设置过期时间的功能、发布订阅消息系统、定时器、计数器。
三、基础知识
基础命令
- 测试redis在本机上的性能:
- docker exec -it 容器ID bash 进入到redis容器实例
- cd /usr/local/bin/ ls -l 查看安装的redis
- redis-benchmark 执行redis-benchmark 对redis进行测试
- 默认redis创建16个数据库(0~15)通过
- select n 来选择数据库
- client list 查看当前连接的客户端
- dbsize 查看数据的key-value对的个数
- set key xxx 在当前库添加一个数据(会对已有数据进行覆盖)
- setnx key xxx 当key不存在时才添加数据(避免覆盖)set if not exist
- mset k1 v1 k2 v2 一次添加多个数据
- get key 查询key
- mget k1 k2 k3 一次get多个值
- keys * 查看所有的key 可以通过keys k? 来筛选数据 符合k?的会被查出来
- flushdb 清除当前库
- flushall 清除所有库
- exists key名字 判断key是否存在
- move key db 将当前键值对移到新的库(db为0~15)当前库就没有了
- expire key 秒钟 为当前数据设置有效期
- ttl key 查看数据还有多久过期 -1 表示永不过期 -2 表示已经过期(就会从中删除)
- type key 查看key的类型
- del key 删除key
数据类型
1. 字符串
- append k1 xxx 在k1对应的value字符串后追加xxx
- strlen key 得到key的长度
- incr key key的值加一(数字才能加减)
- incrby key 3 key的值加3(其他同理)
- decr key 减少key的值
- setrang key 3 xxx 从第三个值开始设置为xxx 后面不变
- getrang key 0 3 获取key的第0到第3位置的字符
- setex key 秒数 value 设置key的有效时间 (set with expire)
2.List
- lpush list a b c d e 添加list列表,left push 在原有的基础上的左面开始添加 (先进后出)
- rpush list 1 2 3 4 5 添加list列表,right push 在原有的基础上的右面面开始添加(先进先出)
- lrang list 0 -1 从左到右遍历列表到结束
- lpop list 从左面删除y一个
- rpop list 从右面删除一个
- lindex list n 获取下标为n的那个数据
- lrem list n m 在list列表中删除n 个 value为m的数据
- ltrim key 开始的index 结束的index 截取key的指定范围值后再付给key
- rpoplpush 源列表 目标列表 将源列表的右边那个移除一个再将其从左边加到目标列表
- lset key index value 设置指定下标元素的值
- linsert key before/after 值1 值2 再值1 前面或者后面添加一个元素
3.set
5. Zset
文件位置
- 初始的配置文件要备份一份
- 文件位置:/usr/local/etc/redis/redis.conf 参考docker安装redis中内容
Units单位
- 1k -> 1000
- 1kb -> 1024
m mb g gb 以此类推(不支持bit,大小写不敏感)
INCLUDE
redis.conf 作为总的配置文件,里面可以包含其他的配置文件
GENERAL
安全
- 默认是不开密码的
- 设置密码(在进入到redis-cli之后才可以)
- config get requirepass 查询获取当前密码
- config set requirepass “123456” 将redis的密码设置为123456
- auth 123456 进入redis之后,在执行命令之前需要通过此方式输入密码来验证
注“:通过config get dir 命令也可以获取到运行redis的目录,因此日志相关内容也在这个目录下
LIMIT限制
- Maxclients 最大的可连接客户端数量(默认10000)
- Maxmemory 最大内存
Maxmemory-policy 缓存的过期策略 六种过期策略。
- Volatile-lru 使用LRU(最近最少使用)算法移除key,只对设置了过期时间的key
- Allkeys-lru 使用LRU(最近最少使用)算法移除key
- Volatile-random 在过期集合中移除随机的key,只对设置了过期时间的键
- Allkeys-random 移除随机的key
- Volatile-ttl 移除ttl最小的key,即那些快过期的key
- Noeviction 不进行移除,针对写操作会返回错误信息,永不过期(默认永不过期 基本不用该方式)
- Maxmemory-samples LRU算法和TTL算法的样本数量 默认5个
常见配置
参考Redis常用配置文件
五、持久化
1. RDB
RDB:(Redis DataBase )在指定的时间间隔内将内存中的数据集快照写入磁盘(Snapshot快照),恢复时是将快照文件读到内存里。Redis会单独创建(fork)一个子进程来进行持久化,将数据写入到一个临时的文件中,待持久化结束以后,在将这个临时文件替换上一次持久化好的文件。过程中主进程不进行IO操作,来确保极高的性能(最大化redis性能)。试用于需要进行大规模数据恢复,且对数据完整性不是很敏感的情况(最后一次持久化后的数据可能丢失)。
Fork: 用来复制一个与当前进程一样的进程,新进程的所有数据都和当前的进程一致,是一个全新的进程,并作为原进程的子进程。
save m n:bgsave自动触发的条件;如果没有save m n配置,相当于自动的RDB持久化关闭,不过此时仍可以通过其他方式(命令方式)触发
默认备份方式
备份文件默认保存为dump.rdb
- 一分钟改了一万次
- 五分钟改了十次
- 十五分钟改了一次
save 执行后马上对数据进行备份,阻塞状态,备份时前台没办法写数据
bgsave 执行后马上对数据进行备份,后台进行,前台还可以写数据
主机和备份的机器使用两台,写个脚本将本地的保存数据更新到另一台机器上
恢复数据: 将备份文件dump.rdb放到redis对应的存放备份文件的目录,通过config get dir获取路径 ,当dump文件出现问题时,可以参考aof里面修复的方式来修复dump文件。
试用场景:
- 试用于大规模数据恢复
- 对数据的完整性要求不高的情况
缺点:
- 由于是隔一段时间备份一次,如果宕掉,则最后一次快照的数据会丢失
- Fork时内存数据会克隆一份,因此会有两倍的膨胀性需要考虑
2. AOF(Append Only File)
- 简介:以日志的形式记录每个写操作,只允许追加文件,不允许改写文件,redis启动之初会读取该文件并重新构建数据(根据日志内容,将写指令从前到后执行一遍,完成数据恢复)。
文件路径
- 文件名:appendonly.aof
- 路径:通过config get dir获取路径
- 记录所有的写文件操作,当然也包括shutdown(如果执行,则文件的最后也会保存这个命令),虽然实际不可能使用shutdown。
- 当rdb和aof同时存在时,先找AOF,再找dump文件。
- redis-check-aof —fix appendonly.aof 当因为断电、延时、丢包等原因,导致aof文件的最后出现乱码,可以通过此命令修复。redis-check-aof 会把所有不符合其语法规范的命令统统删掉。
配置策略:
- appendonly no 默认是不开的,但是不知道为什么我的配置文件是只开启了aof,可能是因为没有按照配置文件启动。
- Appendfsync
- Always:同步持久化,有数据变更就更新,性能很差,数据完整性很好
- Everysec:默认设置,异步操作每秒设置一次,如果一秒内宕机,则数据有丢失。
- No
Rewrite
- 简介:AOF采用的是文件追加的方式,文件会越来越大,因此增加了重写机制,当AOF文件大小超过所设定的阈值,Redis 会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。
- 指令:bgrewriteaof
- 重写原理:持续增长过大时,会fork出一条新进程来将文件重写,(先写临时文件,最后再rename)类似于快照:不是重写原有的aof文件,而是将将整个内存的数据用命令方式重新写了一个新的aof文件。
- 重写的触发机制: redis会记录上一次重写时文件大小,默认配置是当aof文件是上次rewrite后的一倍,且文件大于64M时触发。(真正的大公司这里起步是3G,可以通过这个来看公司的业务情况和技术)
- 缺点:aof文件要远大于rdb文件,恢复速度慢于rdb。AOF每秒同步策略较好,运行效率慢于RDB。
3.持久化选择
- 因为RDB文件只做后备用途,因此建议只在Slave上持久化RDB文件,15分钟备份一次就够了。 save 900 1
- 开启AOF的好处是最恶劣的情况下也只会丢失不到2秒的数据,代价是带来了持续的IO,Rewrite过程(将数据写到新文件,此时会产生系统波动)中造成的阻塞是不可避免的,因此只要硬盘许可,尽量减少AOF Rewrite的频率,所以将AOF重写的基础大小设置的大一些,比如5GB,然后超过原本100%大小时重写,可以适当更改。
- 不开启AOF,仅靠Master-Slave Replication 实现高可用性,可以省掉一大笔IO,也减少了rewrite时的系统波动,但是Master和Slave如果同时宕掉,会丢失十几分钟的数据,启动时需要根据Master和Slave中较新的文件来恢复数据。
六、Redis事务
简介:可以一次执行多个命令,本质是一组命令的集合,事务中所有的命令都会序列化,不加赛。2.2版本以上支持CAS(Check And Set)。
基本命令
- MULTI 开启一个事务块 最后一个字母是大写 i
- EXEX 执行事务块内的所有命令
- DISACRD 取消事务(放弃事务块内的所有命令)
- WATCH key [key …] 监视一个或者多个key,在事务执行之前,如果被监视的key被改动,则事务将被打断。
- UNWATCH 取消对所有key的监视
注:
- 执行的命令中如果有一个有问题(加入命令时就报错,相当于编译报错),则全部命令都不能执行
- 如果哪个命令在执行时才会报错,则其他命令不受影响的继续执行
WATCH监控(乐观锁)
1.相关概念
- 乐观锁:相当于锁一行数据,更新时会判断在此期间有没有人更新这个数据(比如版本号机制:加一个version字段,改完version加一)
- 悲观锁:相当于锁表(基本不用)
2. 注意事项
- 一旦执行了unwatch,则exec之前加的监控锁都会被取消。
七、消息订阅发布
很少用,消息订阅功能。
八、主从复制(读写分离)
简介:
主机数据更新后,根据配置和策略,自动同步到备机的master/slaver机制,Master以写为主,Slaver以读为主。
用途:
- 读写分离(只有主机可以写数据,而从机是不能执行写操作的)
- 容灾恢复
使用:
- 配从不配主
- 从库的配置方式: slaveof 主库的IP 主库的端口
- 每次与master(主机)断开连接以后,都需要重新连接,除非配置到redis.conf文件中
- info replication 可以查看当前的redis是主机还是从机,与之对应的从机,连接状态等信息。
- 不同的机器需要配置的地方
- 拷贝多个配置文件到不同机器并根据需要命不同的名字
- 更改相应的pid文件的名字
- 可以全部采用默认端口(或者在配置文件中将端口也改掉)
- log文件名也可进行对应的修改
- dump.rdb 和 appendonly.aof文件也可进行对应的修改
- 常用方式:一台主机两台备用机
- 通过上述的方式将某一个redis配置成从机后,所有的数据(包括在配置成从机之前主机的数据)都会备份到从机。
一主二从:
简介:一个默认为主机,其他的两个配置为从机
1. 主机停掉(故障)
从机处于原地待命的状态,并不会变为主机,数据也不会丢失。
当主机重新启动后原有关系依然维持。
2. 从机故障
- 原有的其他从机不受影响
- 重新启动挂掉的从机后,它就会变成主机模式(配置文件没有配置的情况下),需要重新将其设置为从机。
去中心化:
简介:Slave1也可以作为下一个Slave2的Master,Slave1可以接受其他Slave2的连接和同步的请求,那么这个Slave1作为链条中的下一个Master可以有效减轻Master的写压力(往从机写数据的压力)。
1. 配置方式
将1设为主机,将2设置为1的从机,将3设置为2的从机。
2. 特点
- 后面的所有从机都对主机进行了备份,因此数据是依次向后备份传递的
- 第二个机器(中间那个)的角色是从机 ,虽然它下面还连了一个从机。
从机变主机:
1. 一主二从模式下
- 主机挂掉以后
- slaveof no one 在从机中执行该命令,将从机变主机,当前数据库停止与其他数据库的同步
- 而后需要将另外一个从机重新设置为当前新主机的从机(因为他还处于待命状态,等待原有主机启动)。
2. 去中心化方式下
从机变主机(自动版-重要)
1. 简介:
也叫哨兵模式(Sentinel Mode),从后台监控主机是否出现故障,如果出现故障,则根据投票数来自动的将从库转变为主库。
2. 配置使用(一主二从下)
添加 sentinel.conf 文件(文件的名字固定,最后一个字母为小写L)
添加内容到文件:sentinel monitor 被监控的数据库名(自己起一个) IP 端口 1
注:数据库名和IP、端口 都是被监控的主机的 1 表示主机挂掉后通过投票方式选从机
1
2port 6379
sentinel monitor host 118.25.50.73 6379 1redis-sentinel /xuwei/myredis/conf/sentinel.conf 启动redis哨兵对主机进行监控。
- 注:文件中可以写多行,来监控多个Master
- 主机挂后,两个从机会自成一套体系(一主一从),当原主机再次启动时,就会变成新主机的从机。
3. 疑问
- 哨兵程序是在主机下运行的嘛?如果主机直接强制被关机了怎么办?是否可以在另一台机器上运行。还是说这个方式仅仅是为了防止数据库出现异常而停止服务。
- 当主机出现问题以后,另一台机器变成了主机,那么后台如何据此来改变访问的端口?后台是否可以配置备用的端口。
- 通过修改端口启动多个 sentinel ,此时是
- 更多参考:Redis Sentinel
复制原理:
1.相关概念
- 全量复制:slave收到数据文件以后,将其加载到内存 (首次或重新连接时)
- 增量复制:Master将新的修改命令依次发给slave,完成同步。
- slave成功连接到master以后会发送一个sync(sychronise)命令
- Master收到sync以后,会启动后台的存盘进程,收集所有收到的用于修改数据集的命令,执行完以后,将整个数据文件传送到slave,完成一次同步。
...
...
本文为作者原创文章,未经作者允许不得转载。