NoSQL
- 定义:泛指非关系型数据库。不需要固定的模式,无需多余的操作就可以横向扩展。
- 特点
- 易扩展
- 大数据量高性能
- 多样灵活的数据模型
- RDBMS vs NoSQL
- 3V+3高
海量(Volume)、多样(Variety)、实时(Velocity)
高并发、高可扩、高性能
- 分类
- KV键值
- 文档型数据库
- 列存储数据库
- 图关系数据库
-
CAP原理
- C:Consistency(强一致性)
- A:Availability(可用性)
- P:Partition colerance(分区容错性)
最多只能满足两个:
- CA:单点集群,可扩展性不太强大,传统Oracle
- CP:性能不是特别高,Redis、Mongodb
- AP:对一致性的要求低,大多数网络架构的选择
分区容错性是必须实现的,只能在一致性和可用性之间选择
BASE:为解决关系型数据库强一致性引起引起的可用性降低而提出的解决方案。
- 基本可用(Basically Available)
- 软状态(Soft state)
- 最终一致(Eventually consistent)
Redis
概述
- 定义:REmote DIctionary Server(远程字典服务器),用C编写,是一个高性能的(key/value)分布式内存数据库,基于内存运行,并支持持久化的NoSQL数据库。
- 特点
- 支持数据持久化,可以将内存中的数据保存在磁盘中,重启时可再次加载进行使用
- 不仅支持简单的key-value类型数据,还提供list、set、zset、hash等数据结构的存储
- 支持数据备份,即master-slave模式的数据备份
- 作用
- 内存存储和持久化;支持异步将内存中数据写到磁盘上,同时不影响继续服务
- 取最新N个数据的操作(List)
- 模拟类似于HttpSession这种需要设定过期时间的功能
- 发布、订阅消息系统
- 定时器、计数器
- 杂
- 单进程,使用了Epoll
- 默认16个数据库,类似数组下表从零开始,初始默认使用0号库
- Select命令切换数据库
- Dbsize查看当前数据库的key数量
- Flushdb:清空当前库
- Flushall:通杀全部库
- 统一密码管理:16个库都是永阳的密码
- redis索引都是从0开始
- 默认端口6379
数据类型
- 五大数据类型
- String(字符串):key-value;二进制安全,可以包含任何数据,value最多可以是512M
- Hash(哈希,类似java里的Map):一个键值对集合;适合存储对象
- List(列表):简单字符串列表,按插入顺序排序,可以添加元素到头部或尾部;底层实际是个链表
- Set(集合):string类型的无序集合;通过HashTalbe实现
- ZSet(sortes set:有序集合):string类型的有序集合,且不允许重复;每个元素都会关联一个double类型的分数;redis通过分数来为集合中成员从小到大排序;zset成员是唯一的,但分数score可以重复
-
键(key)
- keys*
- exists key名:判断某个key是否存在
- move key db:移除
- expire key 秒:为给定key设置过期时间
- ttl key:查看还有多少秒过期,-1为永不过期,-2为已过期
- type key:查看key的类型
-
字符串(String)
单值单value
- set/get/del/append/strlen
- incr/decr/incrby/decrby:数字才能加减;incr每次加1;incrby每次加指定数字
- getrange/setrange:getrange获取指定区间范围的值,类似between…and…,0到-1表示全部;setrange设置区间范围内的值,setrange key值 具体值
- setex(set with expire)键秒值/setnx(set if not exist)
- mset/mget/msetnx
- getset(先get再set)
-
列表(List)
单值多value,头尾操作效率高
- lpush/rpush/lrange
- lpop/rpop
- llndex:按照索引下标获得元素
- llen
- lrem key名:删N个value
- ltrim key名 开始index 结束index:截取指定范围的值后再赋值给key
- rpoplpush 源列表 目标列表
- lset key index value
- linsert key before/after 值1 值2
-
集合(Set)
单值多value
- sadd/smembers/sismember
- scard:获取集合里面的元素个数
- srem key value:删除集合中元素
- srandmember key 某个整数:随机出现几个数
- spop key:随机出栈
- smove key1 key2 在key1里的某个值:将key1里的某个值赋给key2
- sdiff:差集
- sinter:交集
- sunion:并集
-
哈希(Hash)
KV模式不变,但V是一个键值对
- hset/hget/hmset/hmget/hgetall/hdel
- hlen
- hexists key key里某个值的key
- hkeys/hvals
- hincrby/hincrbyfloat
- hsetnx
-
有序集合Zset(sorted set)
在set基础上,加一个score值,之前set是k1 v1 k2 v2,现在zset是k1 score 1 v1 k2 score2 v2
-
zadd/zrange [withscores]
-
zrangebyscore key 开始score 结束score […]
withscores
( : 不包含
limit 开始下标步 多少步
-
zrem key 某score下对应的value值:删除元素
-
zcard key/zcount key score区间/zrank key value值/zscore key value值:获得下标值/获得分数
-
zrevrank key value值:逆序获得下标值
-
zrevrange
-
zrevrangebyscore key 结束分数 起始分数
-
配置文件 redis.conf
-
位置
-
Units单位:配置大小单位,只支持bytes,对大小写不敏感
-
Includes包含
-
General通用
-
Snapshotting快照
- save: 在配置文件中 save 秒钟 写操作次数 禁用 save “” / 直接使用save命令立刻备份
- stop-writes-on-bgsave-error:默认yes,备份失败时停止写;配置成no,不在乎数据不一致
- rdbcompression:默认yes,对于存储到磁盘的快照,设置是否压缩存储。采用LZF算法,消耗CPU
- rdbchecksum:默认yes,存储快照后,用CRC64算法进行数据校验,会增大10%性能消耗
- dbfilename:
- dir
-
Replication复制
-
Scurity安全
-
Limits限制
-
Append only mode追加
-
appendonly:默认no
-
appendfilename
-
appendfsync:
always:同步持久化,每次发生数据变更会立刻记录到磁盘,性能较差但数据的完整性较好
everysec:默认,异步操作,每秒记录,如果1秒内宕机,有数据丢失
no
-
no-appendfsync-on-rwrite:重写时是否可以运用appendfsync,默认no,保证数据安全性
-
auto-aof-rewrite-min-size:设置重写基准值
-
auto-aof-rewrite-percentage:设置重写百分比
-
-
常见配置
持久化
RDB(Redis DataBase)
-
定义:在指定时间间隔内将内存中的数据集快照写入磁盘。恢复时是将快照文件直接读到内存中。
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程结束,再用这个临时文件替换上次持久化好的文件。
整个过程中主进程不进行任何IO操作,确保了极高的性能。
如果需要进行大规模的数据恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加高效。RDB的缺点是最后一次持久化的数据可能丢失。
-
fork:复制一个与当前进程一样的进程。新进程的所有数据(变量、环境、程序计数器)数值都和原进程一致,这是一个全新的进程,并作为原进程的子进程。
-
RDB保存的是dump.rdb文件 (在redis.conf中配置: save 如果禁用:save “”)
-
配置位置:redis.conf --> save
-
如何触发RDB快照:
- 配置文件中默认的快照配置 冷拷贝后重新使用(cp dump.rdb dump_new.rdb)
- 命令save(只管保存,全部阻塞)和bgsave(在后台异步执行,同时还可响应客户端请求。可通过lastsave获取最后一次成功执行快照的时间)
- flushall:也会产生dump.rdb,但里面是空的,无意义
-
如何恢复
将备份文件(dump.rdb)移动到redis安装目录并启动服务即可
-
优势
- 适合大规模数据恢复
- 对数据完整性和一次性要求不高
-
劣势
- 在一定间隔时间做一次备份,如果redis意外down掉,会丢失最后一次快照后的所有修改
- fork的时内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
-
如何停止:
redis-cil config set save “”
AOF(Append Only File)
- 定义:以日志形式来记录每个写操作,将redis执行过的所有写指令记录下来,只许追加文件但不可改写文件,redis启动之初会读取该文件,将写指令从前到后执行一次完成数据的恢复工作。
- AOF保存的是appendonly.aof文件
appendonly默认no
-
配置位置:redis.conf --> appendonly:默认no
-
启动/修复/恢复
-
正常恢复:
启动:设置appendonly为yes
将有数据的aof文件复制一份保存
恢复:重启redis然后重新加载
-
异常恢复
启动:设置appendonly为yes
备份被写坏的aof文件
修复:redis-check-aof --fix进行修复
恢复:重启redis然后重新加载
-
-
rwrite
- 定义:AOF采用文件追加方式,文件会越来越大,为避免而子女增重写机制,当文件大小超过设定的阈值时,redis会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可使用命令bgrwriteaof
- 重写原理:AOF文件持续增长而过大时,会fork出一个新进程来将文件重写(先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条set语句。重写aof文件的操作,并没读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,和快照有点类似
- 触发机制:会记录上次重写时的aof大小,默认配置是当aof文件是上次rwrite后大小的一倍且文件大于64M时触发
-
优势
- 总是同步(appendfsync:always)
- 每秒同步(appendfsync:everysec)
- 不同步(appendfsync:no)
-
劣势
- 相同数据集的数据而言AOF文件远大于RDB文件,恢复速度慢于RDB
- AOF运行效率要慢于RDB,每秒同步策略效率较好,不同步效率和RDB相同
使用选择
- 只做缓存:若只希望数据在服务器运行时存在,也可以不使用任何持久化方式
- 同时开启两种持久化方式:
性能建议
事务
-
定义:可以一次性执行多个命令,本质是一组命令的集合。一个食物中的所有命令都会序列化,按顺序串行化执行而不会被其他命令插入,不许加塞。
-
作用:一个队列中,一次性、顺序性、排他性地执行一系列命令
-
用法
redis对事务是部分支持
-
常用命令
-
正常执行:MULTI + EXEC
-
放弃事务:MULTI + DISCARD
-
全体连坐:
-
冤头债主
-
watch监控
悲观锁/乐观锁/CAS(check and set)(乐观锁:提交版本必须大于当前版本才能执行更新)
watch类似乐观锁,事务提交时,如果key的值已经被别的客户端改变,比如某个list已被别的客户端push/pop过了,整个事务队列都不会执行
通过watch命令在事务执行之前监控了多个keys,若在watch之后又任何key的值发生了变化,exec命令执行的事务都将被放弃,同时返回nullmulti-bulk应答已通知调用者事务失败
-
消息发布订阅
-
定义:进程间的一种消息通信模式,发送者(pub)发送消息,订阅者(sub)接收消息。
-
命令
主从复制(Master/Slave)
-
定义:主机数据更新后根据配置和策略,自动同步到备机的master/slave机制,master以写为主,slave以读为主。
-
作用:读写分离、容灾恢复
-
配置
-
配从(库)不配主(库)
-
从库配置:slaveof 主库ip 主库端口
每次与master断开后,都需重新连接,除非配置进redis.conf
-
修改配置文件
拷贝多个redis.conf文件
开启daemonize :yes
PID文件名字
指定端口
log文件名字
dump.rdb名字
-
常用
一主二仆
薪火相传
反客为主
-
复制原理
-
哨兵模式
定义:反客为主的自动版,能够在后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。
步骤:
一组sentinel能同时监控多个master -
复制的缺点
复制延时
-