【总结】redis
一.redis概述
1.nosql概念
NoSql:即Not-onlySQL。非关系型数据库,作为关系型数据库的补充
2.redis概念
redis(remote dictionary server)c语言开发的一个键值对数据库。单机qps(每秒读取数量)5W+
3.redis数据类型
1.string
(1)set key value 添加/修改数据
(2)get key 获取数据
(3)del key 删除数据
(4)mset key1 value1 key2 value2 添加/删除多个数据
(5)mget key1 key2 获取多个数据
(6)strlen key 获取字符串长度
(7)append key value 追加信息到原始信息后
(5)incr key 值增加1
(6)incrby key num 值增加num
(7)decr key 值减1
(8)decyby key num 值减num
(9)incrbyfloat key num 增加一个浮点数值
(10)set key seconds value 设置声明周期Xsecond秒(投票)
2.hash
底层使用hash表实现数据存储 key field vlaue
(1)hset key field value 添加/修改数据
(2)hget key field 获取数据
(3)hgetall key 获取key对应的所有数据
(4)hdel key field 删除数据
(5)hmset key field1 value1 field2 value2
(6)hmget key field1 field2
(7)hlen key 哈希表中字段数量(field)
(8)hexists key field 哈希表是否存在某个指定字段
(9)hkeys key 获取所有的field
(10)hvals key 获取所有的values
3.list
保存多个数据,底层使用双向链表实现
(1)lpush key value1 value2 添加/修改数据
(2)rpush key value1 value2 添加/修改数据
(3)lrange key start end 获取范围内数据
(如果想lrangge读到正序的,采用rpush进)
(4)lindex key index 查看某个位置的值
(5)llen key 获取长度
(6)lpop key 获取并移除数据
(7)rpop key 获取并移除数据
(8)blpop key1 timeout 阻塞等待一段时间,获取到就取出(类似于mq)
4.set
与hash存储结构完全相同,仅存储键(field),不存储值(nil),并且值不允许重复
(1)sadd key member1 添加数据
(2)smembers key 获取全部数据
(3)sismember key member 判断集合是否包含指定数据
(4)scard key 获取集合数据总量
(5)srandmember key [count] 随机获取集合中指定数量的数据
(5)spop key 随机获取某个数据并移出集合
(6)sinter key key2交集
(7)sunion key2 并集
(8)sdiff key3 差集
(9)sinterstore des key1 key2 交集保存到des集合
5.sorted_set
排序,在set的基础上添加可排序字段
(1)zadd key score member1 添加
(2)zrange key start stop 获取全部数据
(3)zrem key member 删除
(4)zrangebyscore key min max 按条件获取数据
(5)zremrangebyscore key start stop 按条件删除数据
4.key通用操作
(1)del key 删除指定key
(2)exists key 获取key是否存在
(3)type key 获取key类型
(4)expire key seconds 为key设置有效期
(5)ttl key 获取key的有效时间
(6)persist key 转为永久
(7)keys * 查询key
5.db操作
(1)select index 切换数据库
(2)move key db 数据移动
(3)flushdb 清空当前数据库
(4)flushall 清空所有数据库
(5)dbsize 数据总量
二. redis持久化
1.rdb(redis database)
把当前内存中的快照写入磁盘
1.命令
save 手动的保存一次数据
shutdown 关闭服务器时指定保存
2.rdb基本配置
redis-6379.conf
dbfilename dump-6379.rdb #文件名
rdbcompression yes #开启压缩
rdbchecksum yes #开启加载检测
3.rdb执行方案
(1)save
注意:save指令执行会阻塞当前redis服务器,直到当前rdb过程执行完,可能造成长时间阻塞,线上环境不建议使用
(2)bgsave
调用fork函数生成子进程,解决了save的阻塞问题
stop-writes-on-bgsave-error yes 后台存储过程出现错误,是否停止保存操作
(3)自动执行
配置文件加配置
范例:
save 900 1 #900秒内1个key发生变化就去执行
save 300 10
save 60 10000
4.rbd三种方式对比
方式 | save指令 | bgsave指令 |
---|---|---|
读写 | 同步 | 异步 |
阻塞客户端 | 是 | 否 |
额外内存消耗 | 否 | 是(两个进程) |
启动新进程 | 否 | 是 |
自动执行跟bgsave一样
5.rdb优缺点
优点:
(1)RDB是一个紧凑压缩的二进制文件,存储效率较高
(2)rdb存储的是redis在某个时间点的数据快照,非常适用于数据备份,全量复制等场景
(3)rdb恢复速度比aof快
缺点:
(1)无法做到实时持久化,有较大的可能性丢失数据
(2)bgsave要利用fork创建子进程,要牺牲掉一些性能
2.aof(append only file)
以日志的方式记录每次写命令,重启时再执行aof中的命令达到数据恢复的目的(是目前redis持久化的主流方式)
1.aof写数据的三种策略
(1)always(每次):每次写入操作都同步到aof文件中
(2)everysec(每秒):每秒将缓冲区中的指令同步到aof中(默认配置)
(3)no(系统控制):由操作系统控制写入aof的周期
always一定会保证数据不丢失吗?先把写命令追加到aof buffer中,下一次进入事件循环循环后,再将buffer写到磁盘上。那么也就是说,这次写到磁盘上的内容是上一个事件循环产生的
所以,即使设置为always,也会丢失一个循环的数据
2.aof功能开启
配置文件中
appendonly yes
appendfsync always|everysec|no #AOF写数据策略
3.aof重写
AOF重写的目的是为了解决AOF文件体积膨胀的问题,使用更小的体积来保存数据库状态
(1)规则
①忽略无效指令。(如对某个key的多条set只取最后一条 )
②对同一数据的多条写命令合并为一条命令(如list push多个数据最后转化为一条)
(2)重写方式
①手动重写
bgrewriteaof
②自动重写
auto-aof-rewrite-min-size size #自动重写最小尺寸
auto-aof-rewrite-percentage percentage #达到基础尺寸的百分比重写
3.rdb和aof比较
持久化方式 | RDB | AOF |
---|---|---|
占用存储空间 | 小(数据级:压缩) | 大(指令级:重写) |
存储速度 | 慢 | 快 |
恢复速度 | 快 | 慢 |
数据安全性 | 会丢失数据 | 依据策略决定 |
消耗资源 | 高 | 低 |
启动优先级 | 低 | 高 |
三. 事务
1.事务的基本操作
multi 开启事务
exec 执行事务
discard 取消事务
2.redis事务和关系型数据库事务的区别?
redis事务没有回滚。这时,在redis事务执行的过程中,如果发生错误。要分两种情况:
(1)语法错误
multi后执行3个命令,一个语法错误。另外两个正确的也不会生效
(2)运行错误
multi后执行3个任务,一个运行错误(eg:用sadd操作一个list),另外两个正确的会生效
怎么解决:这里我们一般采取日志记录然后业务补偿的方式来处理(但是一般情况下,在redis做的操作不应该有这种强一致性要求的需求,我们认为这种需求为不合理的设计)
3.高级特性
watch key 对key添加监视锁,如果再exec之前key发生变化,终止事务执行
unwatch 取消对key的监视
setnx key value 设置分布式锁
expire key second 设置分布式锁的过期时间(防止死锁)
四.删除策略
1.过期数据
设置了过期时间的key,到达过期时间并不会立即删除
2.过期数据删除策略
redis中使用的是惰性删除+定期删除
1.定时删除
一到key的过期时间,立即执行删除操作
缺点:不管cpu忙不忙,立即执行,可能会影响redis工作效率
2.惰性删除
数据到达过期时间,不做处理,下次访问该数据时再处理
缺点:内存压力大
3.定期删除
周期性轮询redis库中的时效性数据,采取随机抽取策略,利用过期数据占比的方式控制删除频度
五. 主从复制
1.主从复制工作流程
(1)建立连接:建立slave到master的连接,使master能识别slave,并保存slave端口号
方式一:客户端发送命令
salveof masterip masterport
方式二:启动服务器参数
redis-server -slaveof masterip masterport
方式三:服务器配置
slaveof masterip masterport
断开连接命令:slaveof no one (从服务器)
(2)数据同步:slave初次连接master后,复制master中所有数据到slave
包括全量复制和增量复制:①全量复制:master生成rdb文件,通过socket发送给slave(rdb)
②增量复制:恢复进行全量复制过程中执行的所有的数据(aof)
(3)命令传播:master将接收到的数据变更命令发送给slave,slave接收后执行命令
2.心跳机制
进入命令传播阶段,使用心跳机制维护,确保双方连接保持在线
master心跳:PING 确保salve在线(默认周期10s)
slave心跳: replconf ack offset 汇报自己的复制偏移量,获取最新的数据变更指令,同时判断master是否在线(默认1s)
四. 哨兵模式
对于一个有主从关系的分布式系统,对每一台服务器监控。当master发生故障时,通过投票机制在多个哨兵中选择一个leader取处理。切换某个slave为master。
1.配置哨兵
(1)配置1托2主从结构
(2)配置三个哨兵(配置相同,端口不同)sentinel.conf
(3)启动哨兵
redis-sentinel + 配置文件名
2.哨兵工作原理
1.监控阶段
同步各个节点的状态信息(sentinel master slave)
2.通知阶段
各个sentinel之间互相共享收集到的节点信息
3.故障转移阶段
(1)如果某个节点在指定时间没未返回ping成功信息,则认为其主观下线。多个 Sentinel 实例在对同一个服务器做出“主观下线” 判断。就认为它客观下线。
(2)发现主观下线的sentinel向所有其他sentinel发送成为leader的命令,如果其他sentinel还未投过票,则同意,否则拒绝。sentinel发现自己的票数过半就成为leader(否则重新投票)
(3)leader选出后开始操作故障转移,选取一个slave
(①slave-priority优先级最高的 ②选择offset最大的,offset最大说明对master的数据复制的最完整 ③run_id最小的slave节点,run_id最小说明slave节点启动最早)
(4)向选举出来的slave发送 salveof no one命令,变成leader
(5)向其他salve发送命令,使其转为新leader的slave,然后从新master同步数据
(6)leader会把之前的master设为slave,并且每秒ping,当其恢复后,sentinel会使其去复制新master节点的数据
4.redis脑裂问题
因为网络故障,master和slave之间失去联系,但是master和客户端之间网络正常,客户仍像master中写数据。此时slave之间选举出一个master。这时就有两个master,但数据仍从旧的master写入。当网络恢复时,旧的master变成slave,并从新maste同步数据。这样就丢失了网络故障这段时间写入的数据
解决方案:
#连接到master的最少slave数量
min-slaves-to-write 3
#slave连接到master的最大延迟时间
min-slaves-max-lag 10
要求至少3个slave节点,且数据复制和同步的延迟不能超过10秒,否则的话master就会拒绝写请求
五.集群
多主多从的结构
六.企业级解决方案
1.缓存雪崩
在较短的时间内,缓存中较多的key集中过期。用户请求过期的数据,就会从数据库获取数据,数据库无法处理大量请求,导致redis中大量数据被积压,redis服务器崩溃
(1)解决方案:
①构建多级缓存:redis缓存+nginx缓存+ehcache缓存,设置不同有效时间,保证不会被同时淘汰
②修改过期时间,不要让所有数据过期时间都一致
③限流:牺牲一部分客户体验,限制一部分用户请求,降低服务器压力
2.缓存击穿
redis缓存某个key过期,该key的访问量巨大
(1)解决方案:
①对一些高热key,加大此类key的过期时常
②构建多级缓存:redis缓存+nginx缓存+ehcache缓存。设置不同有效时间,保证不会被同时淘汰
3.缓存穿透
大量无效url访问(路径id是数据库没有的),缓存匹配不到,并且数据库也查不到,所以不会设置缓存(一般是黑客攻击)
(1)解决方案:
①缓存null:对查询结果为null的数据进行缓存(失效时间设置短点:30-60s)
②key加密:出现问题,临时启用防灾业务key,在业务层进行key加密,设定校验程序,对过来的key进行校验
【总结】redis的更多相关文章
- 使用redis构建可靠分布式锁
关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...
- Ignite性能测试以及对redis的对比
测试方法 为了对Ignite做一个基本了解,做了一个性能测试,测试方法也比较简单主要是针对client模式,因为这种方法和使用redis的方式特别像.测试方法很简单主要是下面几点: 不作参数优化,默认 ...
- mac osx 安装redis扩展
1 php -v查看php版本 2 brew search php|grep redis 搜索对应的redis ps:如果没有brew 就根据http://brew.sh安装 3 brew ins ...
- Redis/HBase/Tair比较
KV系统对比表 对比维度 Redis Redis Cluster Medis Hbase Tair 访问模式 支持Value大小 理论上不超过1GB(建议不超过1MB) 理论上可配置(默认配置1 ...
- Redis数据库
Redis是k-v型数据库的典范,设计思想及数据结构实现都值得学习. 1.数据类型 value支持五种数据类型:1.字符串(strings)2.字符串列表(lists)3.字符串集合(sets)4.有 ...
- redis 学习笔记(2)
redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...
- redis 学习笔记(1)
redis持久化 snapshot数据快照(rdb) 这是一种定时将redis内存中的数据写入磁盘文件的一种方案,这样保留这一时刻redis中的数据镜像,用于意外回滚.redis的snapshot的格 ...
- python+uwsgi导致redis无法长链接引起性能下降问题记录
今天在部署python代码到预生产环境时,web站老是出现redis链接未初始化,无法连接到服务的提示,比对了一下开发环境与测试环境代码,完全一致,然后就是查看各种日志,排查了半天也没有查明是什么原因 ...
- nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...
- windows+nginx+iis+redis+Task.MainForm构建分布式架构 之 (nginx+iis构建服务集群)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,由标题就能看出此内容不是一篇分享文章能说完的,所以我打算分几篇分享文章来讲解,一步一步实现分 ...
随机推荐
- 极简 Node.js 入门 - 4.3 可读流
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...
- 基于vue2定义自己的图表echart组件
先安装echarts cnpm i echarts -S,然后定义父组件 <template> <div> <echarts :option="echartOp ...
- 记一次数据库主从导致严重的bug解决过程
1.事情起始: 我们每个月要给商家进行出账,所以有定时任务去跑商家的订单和售后进行出账,这个功能已经上线很久了,代码执行多次都没问题,突然有一天,产品找我说出现bug了: 这时,去生产库查询重复的订单 ...
- 【CF1425A】 Arena of Greed题解
原题链接 简要翻译: Mr.Chanek与另一个人玩一个取硬币游戏,他先手.玩家在自己的回合内可以取走硬币堆中的一个.如果硬币堆里有偶数个硬币,玩家也可以选择取走硬币总数的一半.两名玩家都是绝对聪明的 ...
- CLP(FD)有限域上的约束逻辑式编程
译自http://www.pathwayslms.com/swipltuts/clpfd/clpfd.html#_simple_constraints,SWI-Prolog官网所推荐的进阶教程.目前还 ...
- Java知识系统回顾整理01基础04操作符07Scanner
一.Scanner 需要用到从控制台输入数据时,使用Scanner类. 二.使用Scanner读取整数 注意: 使用Scanner类,需要在最前面加上 import java.util.Scanner ...
- python数据结构树和二叉树简介
一.树的定义 树形结构是一类重要的非线性结构.树形结构是结点之间有分支,并具有层次关系的结构.它非常类似于自然界中的树.树的递归定义:树(Tree)是n(n≥0)个结点的有限集T,T为空时称为空树,否 ...
- 【学习笔记/题解】虚树/[SDOI2011]消耗战
题目戳我 \(\text{Solution:}\) 题目很显然可以设\(dp[i]\)表示\(i\)的子树内的关键点都不和\(i\)联通的最小待机,有如下\(dp\)方程: \(v\in son_u, ...
- 【原创】Linux虚拟化KVM-Qemu分析(四)之CPU虚拟化(2)
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: KVM版本:5.9 ...
- JVM(五):JVM模型与GC
确定垃圾 引用计数(存在循环引用问题) 根可达算法 常见的垃圾回收算法 标记清除算法-位置不连续,产生碎片 拷贝算法- 没有碎片,浪费空间 标记压缩-没有碎片,效率偏低(多线程需要进行线程同步,单线程 ...