一. NoSQL
1 NoSQL概述
NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,
泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本身的特点得到了非常迅速的发展。NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题,包括超大规模数据的存储。
(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
2 NoSQL 特点
- 易拓展
NoSQL数据库种类繁多,但是一个共同的特点都是去掉关系数据库的关系型特性。
数据之间无关系,这样就非常容易扩展。也无形之间,在架构的层面上带来了可扩展的能力。 - 大数据量高性能
NoSQL数据库都具有非常高的读写性能,尤其在大数据量下,同样表现优秀。
这得益于它的无关系性,数据库的结构简单。
一般MySQL使用Query Cache,每次表的更新Cache就失效,是一种大粒度的Cache,
在针对web2.0的交互频繁的应用,Cache性能不高。而NoSQL的Cache是记录级的,
是一种细粒度的Cache,所以NoSQL在这个层面上来说就要性能高很多了 - 多样灵活的数据模型
NoSQL无需事先为要存储的数据建立字段,随时可以存储自定义的数据格式。而在关系数据库里,
增删字段是一件非常麻烦的事情。如果是非常大数据量的表,增加字段简直就是一个噩梦。
3 RBMS vs NoSQL
RBMS - 关系数据库管理系统;
- 高度组织化结构化数据
- 结构化查询语言(SQL)
- 数据和关系都存储在单独的表中。
- 数据操纵语言,数据定义语言
- 严格的一致性
- 基础事务
NoSQL
- 代表着不仅仅是SQL
- 没有声明性查询语言
- 没有预定义的模式
- 键 - 值对存储,列存储,文档存储,图形数据库
- 最终一致性,而非ACID属性
- 非结构化和不可预知的数据
- CAP定理
- 高性能,高可用性和可伸缩性
4 聚合模型
- KV键值
- BSON
是一种类json的一种二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌的文档对象和数组对象 - 列族
顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,
对针对某一列或者某几列的查询有非常大的IO优势。

- 图形

二. Redis
1 Redis入门
1.1 概述
Redis:REmote DIctionary Server(远程字典服务器)
是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内存数据库,基于内存运行。并支持持久化的NoSQL数据库,是当前最热门的NoSql数据库之一,也被人们称为数据结构服务器。
1.2 特点
- Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储
- Redis支持数据的备份,即master-slave模式的数据备份
1.3 主要功能
- 内存存储和持久化:redis支持异步将内存中的数据写到硬盘上,同时不影响继续服务
- 取最新N个数据的操作,如:可以将最新的10条评论的ID放在Redis的List集合里面
- 模拟类似于HttpSession这种需要设定过期时间的功能
- 发布、订阅消息系统
- 定时器、计数器
2 Redis安装
2.1 安装步骤
-
下载
http://www.redis.cn/
https://redis.io/ -
将安装包移动到/opt目录下并解压
tar tar -zxvf ****.tar.gz -
下载gcc编译工具
yum -y install gcc-c++ -
进入解压好的文件夹内并编译
make make install -
修改配置文件
vim /opt/redis/redis.config # 将daemonize no 改为 yes 改为了后台启动 # 将bind 127.0.0.1 改为 bind 0.0.0.0 允许远程访问 # 在security中添加 requirepass 123123 设置连接密码为123123 -
加载配置文件启动
redis-server /opt/redis/redis.config # 建议将配置文件拷出来修改 -
关闭
redis-cli shutdown
2.2 Redis命令
- redis-benchmark:性能测试工具
- redis-check-aof:修复有问题的AOF文件
- redis-check-dump:修复有问题的dump.rdb文件
- redis-cli:客户端,操作入口
- redis-sentinel:redis集群使用
- redis-server:Redis服务器启动命令
3 Redis 数据类型
3.1 String
3.1.1 概述
string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个redis中字符串value最多可以是512M。
3.1.2 常用操作
# 新增key-value
set key value [expiration EX seconds|PX milliseconds] [NX|XX]
# EX 将键的过期时间设置为 seconds 秒
# PX 将键的过期时间设置为 milliseconds 毫秒
# NX 只在键不存在时,才对键进行设置操作
# XX 只在键已经存在时,才对键进行设置操作
# 设置key-value 并制定失效时间 seconds
setex key seconds value
# 当且仅当key不存在时,才去设置key-value
setnx key value
# 批量设置k1-v1 k2-v2 k3-v3 ...
mset k1 v1 k2 v2 k3 v3 ...
# 批量获取k1 k2 k3
mget k1 k2 k3
# 获取key的value
get key
# 先获取在设置value
getset key value
# 删除key
del key
# 在key后追加value
append key value
# 获得key长度
strlen key
# key++ 或 key--
incr key
decr key
# key++num 或 key--num
incrby key num
decrby key num
# 截取 index1 到 index2 的内容
# 当 index1 为 0 index2 为 -1 时, 截取全部内容
getrange key index1 index2
# 从 key 的 index 位置开始插入 value 值
setrange key index value
3.2 List
3.2.1 概述
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素导列表的头部(左边)或者尾部(右边)。它的底层实际是个链表。
3.2.2 常用操作
# 从左边给key插入value
lpush key value [value ...]
# 从右边给key插入value
rpush key value [value ...]
# 从左 start 开始到 stop 获取key
lrange key start stop
# 从左弹出一个值
lpop key
# 从右弹出一个值
rpop key
# 按索引获取一个值,索引从做开始记
lindex key index
# 获取key长度
llen key
# 从左开始删除 count 个 value
lrem key count value
# 从左边 start 开始到 stop 截取 key
ltrim key start stop
# 从 source 右端弹出一个元素,并将该元素从左边加入到 destination
rpoplpush source destination
# 从左边开始的 index 值 修改为 value
lset key index value
# 在pivot的 前|后 插入 value
linsert key BEFORE|AFTER pivot value
3.3 Set
3.3.1 概述
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中集合是通过哈希表实现的。
3.3.2 常用操纵
# 添加member,重复元素不添加
sadd key member [member ...]
# 获取key的值
smembers key
# 判断 key 中是否包含 value, 包含返回1,不含返回0
sismember key value
# 获取 key 中的元素个数
scard key
# 删除 key 中的 member
srem key member [member ...]
# 随机展出 count 个元素
srandmember key [count]
# 随机出栈 count 个元素
spop key [count]
# 将 source 中的 member 移除并添加到 destination 中
smove source destination member
# 返回 key1 与 key2 的差集
sidff key1 key2
# 返回 key1 与 key2 的交集
sinter key1 key2
# 返回 key1 与 key2 的并集
sunion key1 key2
3.4 Hash
3.4.1 概述
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
3.4.1 常用方法
# 设置 key 的字段 filed 的值为 value
hset key field value
# 当且仅当 filed 字段不存在于 key 中时才会创建并赋值
hsetnx key field value
# 获取 key 的字段 filed 的值为 value
hget key field
# 同时将多个filed-value赋值给key
hmset key field value [field value ...]
# 同时获取多个filed值
hmget key filed [filed ...]
# 获取全部filed-value值
hgetall key
# 删除一个或多个 filed 字段
hdel key filed [filed ...]
# 获取 key 字段个数
hlen key
# 查看 key 中是否包含 filed 字段, 包含返回1, 不包含返回0
hexists key filed
# 获取 key 中的全部字段
hkeys key
# 获取 key 中的全部值
hvals key
# 为 key 中的 filed 字段值 加上增量 increment
# increment 可为负数,代表减量
# 如果 key 不存在, 会自动新建 key 及 filed 并增量 increment
# 如果 filed 不存在, 会创建 filed 并增量 increment
hincrby key filed increment
# 为 key 中的 filed 字段值 加上增量 increment
# increment 可为负数,代表减量
# 如果 key 不存在, 会自动新建 key 及 filed 并增量 increment
# 如果 filed 不存在, 会创建 filed 并增量 increment
hincrbyfloat key filed increment
3.5 Zset(sorted set)
3.5.1 概述
Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
有序集合的成员是唯一的,但分数(score)却可以重复。集合是通过哈希表实现的 。
3.5.2 常用方法
# 将一个或多个 member 元素及 score 值添加到有序集 key 中
# 如果 key 中已存在 member 那么会更新这个元素的 score 值
# score 可以是整数或双精度浮点数
zadd key [NX|XX] [CH] [INCR] score member [score member ...]
# 展示 key 中 start 到 stop 的值 score 由低到高
zrange key start stop [WITHSCORES]
# 展示 key 中 start 到 stop 的值 score 由高到低
zrevrange key start stop [WITHSCORES]
# 展示 score 在 min 至 max 区间内的值 score 由低到高
zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
# 展示 score 在 min 至 max 区间内的值 score 由高到低
zrevrangebyscore key min max [WITHSCORES] [LIMIT offset count]
# 移除 key 中的一个或多个 member
zrem key member [member ...]
# 获取有序集和 key 的基数
zcard key
# 获取 key 中 在 min 至 max 区间内的元素个数
zcount key min max
# 按 score 由大到小 获取 member 的排名
zrevrank key member
3.6 其他操作
# 获取所有 key
keys *
# 判断 key 是否存在
exists key
# 移动 key 值其他库 本库不存在
move key db
# 设置 key 的过期时间
expire key seconds
# 查看 key 的剩余时间
ttl key
# 查看 key 的类型
type key
4 Redis事务
4.1 概述
Redis事务可以一次执行多个命令(允许再一次单独的步骤中执行一组命令),并且带有以下两个重要保证:
- Redis会将一个事务中的所有命令序列化,然后按顺序执行;
- 执行中不会被其它命令插入,不许出现插队行为.
一个事务从开始到执行会经历三个阶段:
- 开始事务;
- 命令入队;
- 执行事务.

如果执行的某个命令报出了错误,则只有报错的命令不会被执行,而其它的命令都会执行,不会回滚.
4.2 案例
4.2.1 标准事务执行
# 设置账户key1 key2 余额均为100
set key1 100
set key2 100
# 开启事务
MULTI
# 事务中的命令
# key1 增加50 key2 减少50
incrby key1 50
decrby key2 50
# 执行事务
exec
4.2.2放弃事务执行
# 设置账户key1 key2 余额均为100
set key1 100
set key2 100
# 开启事务
MULTI
# 事务中的命令
# key1 增加50 key2 减少50
incrby key1 50
decrby key2 50
# 放弃事务
discard
4.2.3 事务出错演示
# 设置账户key1 key2 余额均为100
set key1 100
set key2 100
# 开启事务
MULTI
# 事务中的命令
# key1 增加50 key2 减少50
set key1 aaa
incrby key1 100
decrby key2 100
# 执行事务
exec

4.2.4 监控事务
watch 关键字用于监控一个或多个key,如果在事务执行之前key被其它命令所改动,那么事务将被打断.
# 设置账户key1 key2 余额均为100
set key1 100
set key2 100
watch key1 key2
# 开启事务
MULTI
# 事务中的命令
# key1 增加50 key2 减少50
incrby key1 100
decrby key2 100
# 执行事务
# 在执行事务之前,在另一个客户端对key1,key2进行操作
exec

使用unwatch关键字可解除对key的监控
5 Redis 数据淘汰策略
- volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰;
- volatile-lfu:从已设置过期的Keys中,删除一段时间内使用次数最少使用的;
- volatile-ttl:从已设置过期时间的数据集中挑选最近将要过期的数据淘汰;
- volatile-random:从已设置过期时间的数据集中随机选择数据淘汰;
- allkeys-lru:从数据集中挑选最近最少使用的数据淘汰;
- allkeys-lfu:从所有Keys中,删除一段时间内使用次数最少使用的;
- allkeys-random:从数据集中随机选择数据淘汰;
- no-enviction(驱逐):禁止驱逐数据(不采用任何淘汰策略。默认即为此配置),针对写操作,返回错误信息
6 Redis持久化
6.1 RDB
RDB是Redis的默认持久化机制,RDB相当于快照,保存的是一种状态.
优点: 快照保存数据和恢复数据极快,适用于灾难备份
缺点: 小内存机器不适用,RDB机制符合要求才会快照保存
保存条件
-
每次服务器正常关闭时;
-
key 满足一定条件时
查看方式,打开config文件 :/SNAPSHOTTINGsave 900 1 //每900秒(15分钟)至少1个key发生变化,产生快照
save 300 10 //每300秒(5分钟)至少10个key发生变化,产生快照
save 60 10000 //每60秒(1分钟)至少10000个key发生变化,产生快照
以上两个条件任满足一个即刻触发
6.2 AOF
它的出现是为了弥补RDB的不足(数据的不一致性),所以它采用日志的形式来记录每个写操作,并追加到文件中。Redis 重启的会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
配置设置
# 1. 开启AOF
appendonly yes
# 2. 设置本地数据文件
appendfilename "appendonly.aof"
# 3. 指定更新条件
appendfsync always # 同步持久化,每次发生数据变化会立刻写入到磁盘中。性能较差当数据完整性比较好(慢,安全)
或 appendfsync everysec # 出厂默认推荐,每秒异步记录一次(默认值)
或 appendfsync no # 不同步
7 其他问题
7.1 缓存穿透
问题描述:
缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库中查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透.
解决方法:
查询时先判断缓存中是否exists key,如果有直接返回查询结果,没有再查询数据库,持久层查询不到就缓存空结果
注意:
当新插入数据的时候,要记得清除原先的空key,否则即便数据库有值也是查询不到的
7.2 雪崩
问题描述:
缓存大量失效的时候,引发大量查询数据库.
解决方法:
- 用锁\分布式锁或队列串行访问
- 缓存失效时间均匀分布
本文深入探讨NoSQL数据库的概念、特点及其与关系型数据库的区别,重点解析Redis的特性、安装步骤、数据类型与操作,以及事务、数据淘汰策略和持久化机制。
1372

被折叠的 条评论
为什么被折叠?



