为什么要用NOsql
大数据一般的数据库无法进行分析处理了。
数据量太大,一个机器放不下
数据的索引(B+Tree),一个机器内存也放不下
访问量(读写混合),一个服务器承受不了
发展过程:优化数据结构和索引-》文件缓存(IO)-》Memcached(缓存)
Nosql的4大分类
KV键值对:redis
文档型数据库: MongoDb(基于分布式文件存储的数据库,处理大量的文档)、ConthDB
MongoDb是一个介于关系型数据库和非关系型中中间的产品。是非关系型数据库中功能最丰富的
列存储数据库
HBase
分布式文件系统
图关系数据库:Neo4j
Redis入门
Remote Dictionary Server 远程字典服务,C语言编写的Key-Value数据库,支持多语言。
免费和开源!
特点:多样的数据类型,持久化,集群,事务
Redis推荐都是在Linux服务器上搭建的。
测试性能
redis-benchmark官方自带的性能测试工具
基础知识
redis默认有16个数据库 databases 16
但是默认使用的是第0个
可以使用select切换数据库命令: select 3
查看DB大小命令:dbszie
查看当前数据库所有的Key命令:keys *
清空当前数据库清除:flushdb
清空全部数据库:flushall
Redis-key:命令
exists key #判断当前的Key是否存在
move key 1#移除当前的key
expire key 10 #设置key时间
ttl key #查看当前过期时间
type key #查看数据类型
redis是单线程的
明白redis是很快的,redis是基于内存操作的,cpu不是redis的性能瓶颈,瓶颈是根据机器的内存和网络带宽,
既然可以使用单线程来实现,就使用单线程了。
redis是C语言写的,官方提供的数据问100000 +的QPS
redis为什么单线程还这么快?
误区1:高性能的服务器一定是多线程的?
误区2:多线程(CPU上下文会切换)一定比单线程效率高?
核心:redis将所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的。
多线程(CPU上下文会切换)。对于内存系统来说,如果内有上下文切换效率就是最高的。
多次读写都是在一个CPU上的,在内存情况下,这个就是最佳方案。
redis的五大数据类型:
String(字符串类型)
append key "字符串" #追加字符串,如果当前字符串不存在,就相当于set了一个
strlen key #得到字符串长度
incr key 自增 、decr 自减
List(列表)
所有的list命令都是L开头的
lpush key #将一个或者多个插入列表的头部
lrange key #查看列表
rpush #将一个或者多个插入列表的尾部
lpop #从头部移除
rpop #从尾部移除
lindex key 0 #通过下标获取值
len #获取长度
lrem #移除集合中的某个值 ,lrange #移除范围
set(集合)
所有的set命令都是s开头
sadd key #往set塞入值
smembers #查看set所有值
sisimember #查看当前元素是否存在
scard key #获取集合个数
srem key value #移除某个元素
Hash(哈希)
本质和string没有什么区别,还是一个简单的key-value
map 集合, key-map集合 key-(key-value)
所有的哈希是H开头的‘
hset key mapkey mapvalue #存值
hget key mapkey #取值
hmset #存多个值
hmget #取多个值
hgettall #全部取出来
hdel key mapkey #删除指定的
Zset(有序集合)
在set的基础上,增加了一个值,set k v zset k score v
zadd key 序号 value #增加一个序号存值
zrange key #查询全部集合
zrangebyscore key -inf +inf #从小到大排序
事务
redis事务本质:一组命令一起执行。一个事务中的所有命令都会被序列化,在事务执行过程中会按照顺序执行。
一次性、顺序性、排他性
redis事务没有隔离级别的概念
所有的命令在事务中,并没有直接被执行,只有发起exec命令的时候才会执行。
redis单条命令保证原子性的,但是事务不保证原子性。
redis的事务: (三个阶段)
开启事务(multi)
命令入队 (需要执行的命令)
执行事务 (exec)
discard 放弃事务
编译型异常:所以命令不会执行。 运行时异常:异常的命令不执行,其他命令会执行
redis实现乐观锁
获取version 更新的时候比较 version, 配合事务cas的方式
redis.conf详解
配置文件unit单位 对大小写不敏感。
inckude (包含,可以包含多个配置文件)
bind 12.7.0.0.1 #绑定IP
protected-mode yes #是否保护模式
port 6379 #设置IP
daemonize yes #默认是no 以守护进程的方式开启
pidfile /var/run/redis_6379.pid # 如果是后台方式运行,需要知道一个pid文件
loglevel notice #日志级别
logfile “”#日志输出的文件位置
databases 16 #数据库的数量
always-show-logo yes #是否显示log
save #持久化规则 redis是内存数据库,没有持久化,断电数据会丢失
save 900 #如果900秒内有一次修改,就进行持久化操作
save 300 10# 如果300秒有10此操作
save 60 10000 #如果60秒内 有一万次
stop-writes-on bgsave-error yes #如果持久化异常,是否继续工作
rdbcompression yes #是否压缩 rdb ,需要消耗cpu资源
rdbchecksum yes #保存rdb文件的时候,进行错误校验
dir ./ #rdb文件保存的目录
redis默认是没有密码的,可以在配置文件设置 命令方式:config set requirepass ,auth 密码登录
requirepass 密码 #设置密码
maxclients 10000#最大连接客户端数量
maxmemory <bytes> #最大内存容量
maxmemory-policp noeviction #内存满了。策略
Redis持久化
RDB
在指定的时间间隔内,由子线程。将内存中的数据集体筷子写入磁盘中,他恢复时是将快照文件直接读取到内存中
redismors RDB 一般情况下不需要修改这个配置
dbfilename dump.rdb
触发机制: save的规则满足的情况下,会自动触发rdb规则,执行flushall命令,退出redis也会产生。
如何恢复rdb文件:
只需要将rdb文件放在我们redis启动目录就可以,redis启动的时候就回自动检测rdb文件
可以用命令 config get dir 查看存放的位置。
优点:适合大规模的数据恢复,对数据的完整性要求不高。
缺点:需要一定的时间间隔进程操作,如果redis意外宕机了,这个最后一次修改数据就没了,fork备份过程中会消耗内存空间。
AOF(追加文件)
将我们的所有命令都记录下了,history
以日志的形式记录每个写操作,将redis执行过程的所有指令记录下了(读操作不记录)
appendonly no #默认是不开启的,需要进行手动配置,只需要改为yes即可
appendonly.aof 日志文件
重启,redis就可以生效。
如果aof日志文件有错误,redis是启动不起来,需要进行修复。redis提供了工具。
修复命令:redis-check-aof --fix appendonly.aof
如果文件正常,重启就可以直接恢复了。
优点:每次修改都同步,文件的完整性会更加好,每秒同步一次,可能会丢失一秒。
缺点:相对于数据文件来说,aof远远大于RDB,修复速度比rdb慢,运行效率也要比rdb慢
Redis发布订阅
是一种消息通信模式,发送者发送消息,订阅者接收消息。
subscribe 频道名 #订阅者订阅一个频道,订阅之后就自动创建
publish 频道名 信息 #发送频道,发布信息
主从复制:
默认情况下,集群中的所有节点都是主节点,一般情况下只用配置从机就好了。
slaveof 主节点IP #在从节点上输入命令
如果要永久配置。在配置文件中配置
去从节点修改配置文件 replicaof
配置好以后,主机负责写,从机负责读。
如果主节点挂了,在没有配置哨兵的情况下,从节点还是一样的不会改变.等到主节点恢复了,数据会还原。
层层链路
主节点-》从节点,主节点-》从节点
如果第一个主节点挂了,中间节点也是无法写入内容。
如果主几点没了,可以在从节点执行命令: slaveof no one 变成主节点。
哨兵模式(自动选举主节点模式)
当主服务器宕机后,需要手动吧一台从服务器切换为主服务器,这时候需要人工干预。
在线上中这种干预肯定是不合适的。下面就用到了一个哨兵
哨兵也要进行集群配置。哨兵每隔一段时间会像redis集群发送消息。如果有一个节点没有回复。
那么那会暂时认为只是出现问题。但是如果所有哨兵都发现这个节点出现问题,该节点下线,
从新由哨兵投票选举新的在从节点中主节点
配置哨兵配置文件 sentinel.conf
sentinel monitor 被监控的名称 IP 1
后面的数字1,代表主机挂了。slave投票看让谁接替成主机
启动哨兵 即可完成
redis-sentinel 配置文件
如果主机挂了,选举新的主机后,该主机又上线之后,就会变成从机。
优点:
哨兵集群,基于主从复制模式,所有的主从配置优点,它全有
主从可以切换,故障可以转移,系统的可用性就回更好
哨兵模式就是主从模式的升级,手动到自动,更加健壮
缺点:
redis集群不太好在线扩容,一旦达到上线,扩容比较麻烦
因为修改很多哨兵的配置,还要对应很多主从节点
redis缓存穿透和雪崩
缓存穿透:
正常逻辑: 查询数据-》服务端去Redis查询,如果有直接返回,如果没有去-》mysql查询,返回,顺便保存进入redis
那穿透逻辑: 突然来非常多的查询-》服务端redis查询,都没有-》请求打进mysql 服务穿透
解决方案:布隆过滤器
是一种数据结构,对所有可能查询的阐述以hash形式存储。
是二种缓存空对象
缓存击穿
缓存继承是指一个key非常热点,在不停的扛着大并发,如果这个key过期时间是60秒。在下一秒虽然会恢复,但是这一秒的空档期
就进入了mysql
解决方案:
设置热点数据永不过期: 不太现实,线上环境设置永不过期数据,容易内存满
加互斥锁: 让所有线程互相抢锁,那么所有请求只有一个请求,进入数据库查询。
缓存雪崩
在某个时间段。redis集体失效,或者全部宕机
解决方案:
rdis高可用:搭建非常多是机器,异地多个
限流降级:让错误提前直接返回,并执行降级策略
数据预热:提前预热数据
总结: