1. NoSQL概述
- Not only SQL
- 没有声明性查询语言
- 没有预定义的模式
- 键值对存储,列存储,文档存储,图形数据库
- 最终一致性,而非ACID属性
- 非结构化和不可预知的数据
- CAP定理
- 高性能,高可用性和可伸缩性
2. 3V + 3高
- 大数据时代的3V
- 海量 Volume
- 多样 Variety
- 实时 Velocity
- 互联网需求的3高
- 高并发
- 高可扩
- 高性能
3. 分布式数据库中CAP原理与BASE
-
CAP
- Consistency:强一致性
- Availability:可用性
- Partition tolerance:分区容错性
-
CAP的3进2
CAP理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求,最多只能同时较好的满足两个。
因此,根据CAP原理将NoSQL数据库分成了三大类:
-
CA
单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大
-
CP
满足一致性,分区容忍性的系统,通常性能不是特别高
-
AP
满足可用性,分区容忍性的系统,通常可能对一致性要求低一些
分区容忍性是分布式系统必须实现的
CA是传统的数据库,AP是大多数网站架构的选择,CP则是Redis、MongoDB这些
-
-
BASE
BASE就是为了解决关系数据库强一致性的问题而引起的可用性降低而提出的解决方案
BASE其实是下面三个术语的缩写:
- 基本可用(Basically Available)
- 软状态(Soft state)
- 最终一致性(Eventually consistent)
它的思想是通过让系统放松对某一时刻数据一致性的要求来换取系统整体伸缩性和性能上的改观。为什么这么说呢,缘由就在于大型系统往往由于地域分布和极高性能的要求,不可能采用分布式事务来完成这些指标,要想获得这些指标,我们必须采用另一种方式来完成,这里BASE就是解决这个问题的办法。
4. Redis 杂项基础知识
- 单进程
- 默认16个数据库,类似书序下标从零开始,初始默认使用零号库
SELECT
:切换数据库,如SELECT 15
DBSIZE
:查看当前数据库的key的数量FLUSHDB
:清空当前库FLUSHALL
:通杀全部库- 统一密码管理,16个库都是同样密码,要么都OK,要么一个也连接不上
- Redis的索引都是从零开始
- 默认端口6379
5. Redis数据类型
5.1 Redis 键(key)
-
keys *
:查看该库所有的key -
exists key
:判断key是否存在 -
move key db
:当前库没有了,被移除了,如move cook 2
,表示将cook键值对移动到下标为2的库 -
expire key 秒
:为给定的key设置过期时间 -
ttl key
:查看当前key还有多少秒过期,-1表示永不过期,-2表示已过期 -
type key
:查看你的key是什么类型
5.2 Redis 字符串(String)
- set/get/del/append/strlen
- incr/decr/incrby/decrby,一定要是数字才能相加减前两个类似 ++/–,后两个类似 +=/-=
- getrange/setrange,类似切片,但是这里是闭区间
setex(set with expire)键秒值
/setnx(set if not exist)
- mset/mget/msetnx
5.3 Redis 列表(List)
- lpush/rpush/lrange
- lpop/rpop
- lindex,按照索引下标获得元素(从上到下)
- llen
- lrem key 删n个value,如
lrem list01 2 3
,表示删除列表中2个3 ltrim key 开始index 结束index
,截取闭区间的内容rpoplpush 源列表 目的列表
lset ket index value
linsert key before/after 值1 值2
下面的类型常用方法偷懒不想写了,需要用到再查,Redis命令都比较简单
5.4 Redis 集合(Set)
5.5 Redis 哈希(Hash)
5.6 Redis 有序集合(Zset)
6. Redis 持久化
-
RDB(Redis DataBase)
在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。
fork 的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程
整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB官方式要比AOF方式更加的高效。
RDB的缺点是最后一次持久化后的数据可能丢失
RDB 保存的是 dump.rdb 文件
-
优势
适合大规模的数据恢复,对数据完整性和一致性要求不高
-
劣势
在一定间隔做一次备份,所以若果Redis意外down掉的话,就会丢失最后一次快照后的所有修改
fork 的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
-
-
AOF(Append Only File)
以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件,但不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
AOF 保存的是 appendonly.aof 文件
-
Rewrite
AOF采用文件追加方式,文件会越来越大,为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof
重写原理:AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也就是先写临时文件最好再rename),遍历新进程的内存中的数据,每条记录有一条的set语句。重写AOF文件的操作,并没有读取旧的AOF文件,而是将这个内存中的数据库内容用命令的方式重写了一个新的AOF文件,类似快照
触发机制:Redis 会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
-
优势
- 每秒同步:appendfsync always,同步持久化,每次发生数据变更会被立即记录到磁盘 ,性能较差但数据完整性比较好
- 每修改同步:appendfsync everysec,异步操作,每秒记录,如果一秒内宕机,有数据丢失
- 不同步:aooendfsync no,从不同步
-
劣势
- 相同数据集的数据而言AOF文件要远大于RDB文件,恢复速度慢于RDB
- AOF 运行效率要慢于RDB,每秒同步策略较好,不同步效率和RDB相同
So, which one?
RDB 持久化方式能够在指定的时间间隔对你的数据进行快照存储
AOF 持久化方式记录每次对服务器的写操作,当服务器重启的时候回会重新执行这些命令来恢复原始的数据,AOF 命令以Redis协议追加保存每次写的操作到文件末尾,Redis还能对AOF文件进行后台重写,使AOF文件的体积不至于过大
只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式
官方建议,同时开启两种持久化方式,在这种情况下,当Redis重启的时候回优先载入 AOF 文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。RDB 的数据不实时,同时使用两者时,服务器重启也只会找AOF文件。那要不要只使用 AOF 呢?作者建议不要!因为RDB更适合用于备份数据库(AOF 在不断变化不好备份),快速重启,而且不会有 AOF 可能潜在的 bug,留着作为一个玩意的手段。
-
7. Redis 事务
可以一次执行多个命令,本质是一组命令的集合。一个事务中的所有命令都会序列化,按顺序地串行化执行而不会被其他命令插入,不许加塞
- MULTI/EXEC