首页 > 其他 > 详细

Redis 学习

时间:2020-09-27 08:26:52      阅读:32      评论:0      收藏:0      [点我收藏+]

Redis

List

基本数据类型:列表,命令都是l开头

lpush list one #将一个或多个值插入列表头部
rpush list two #插入列表尾部
lrange list 0 -1
lrange 0 1
lpop list
rpop list
lren list
lindex list 1 #通过下标获取值
lrem list 1 one #移除指定值
ltrim list 1 2 #截取 [1,2] 截取指定长度 list改变了
rpoplpush  list  list1 #移除元素加入另一item个列表
lset list 0 item#对 0是下标 list 的值进行更新
linsert list before "wold" "vv" #插入值
linsert list after "wold" "new" #插入值

#用作消息队列  lpush lpop rpush rpop

set集合

命令都是s开头,值是不重复的无序的

sadd mylist "hello"
smembers myset   #列举出所有值
sismember myset hello   #查看是否包含元素
scard myset #获取set集合中的内容元素个数
srem  myset  hello #移除集合中指定元素
srandmember myset 2  #随机抽选出指定个数的元素
spop myset  #随机删除key
smove myset myset2 “hello” #移除指定元素到另一个集合
sdiff  set1 set2 #集合set1-set2  
sinter set1 set2 #集合的交集
sunion set1 set2  #集合的并集
#应用  微博,所有关注的人放在同一集合,粉丝也放在同一集合,
#  共同关注 共同好友,二度好友

Hash(哈希)

Map集合,key-map~~时候这个值是一个map集合 命令h开头

本质和String类型没有太大区别,还是一个简单的key-value

hset  myhash field1  kuangshen  #插入某一个值 哈希表
hget  myhash  field1   #获取某一个值
hmset  myhash  field2 v  field3  gg   # 批量插入
hmget   myhash   #获取多个字段值
hdel  myhash  field1  #删除hash指定key字段对应的value值
hgetall myhash  #获取所有key-value值
hlen myhash    #获取hash 表的字段数量
hexists myhash field1  #判断hash指定字段是否存在
hkeys myhash    #获取所有key值
hvals myhash   #获取所有value值
hincrby myhash  field1 1  #加一
hsetnx  myhash  field4 5 #不存在即创建
#hash变更的数据   user name  age  ,尤其是用户信息之类的,经常变动的信息 
# hash适合对象 string适合字符串

Zset(有序集合)

在set的基础上,增加了一个值。命令行z开头

set k1 v1

zset k1 score v1

zadd  myset  1 one
zadd  myset  2 two  3 three
zrange  myset 0 -1
#排序如何实现
zadd  salary  500 zhang
zadd  salary  600 he
zrangebyscore   salary  -inf  +inf #显示范围内的value
zrangebyscore   salary  -inf  +inf withscores   #显示key与score
zrange salary  0 -1  #显示所有的元素
zrem  salary  he  #移除元素
zcard salary  #获取有序集合个数
zrevrange salary  #从大到小进行排序
zcount  myset  1 3 #指定区间的数量
案例:set排序,存储班级成绩,工资表
权重   普通消息,重要消息
排行榜,topk

Geospatial(地理位置)

朋友定位,附近的人,打车距离计算

可以查询一些测试数据

只有六个命令

#geoadd  添加地理位置
geoadd  china:city  116.40  39.90 beijing #添加 经度 纬度 名称  可以添加多个
#规则:两极无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入
geopos china:city beijing  #获取指定地区的经纬度
#两人之间的定位
geodist 命令-返回两个给定位置之间的距离
m ,km,mi英里,ft英尺
geodist china:city  beijing chongqing km
georadius #以给定的经纬度为中心,找出结合某一半径内的元素
#案例 附近的人
georadius china:city 110  30 1000 km
georadius china:city 110  30 1000 km withdist  #返回距离
georadius china:city 110  30 1000 km withcoord  #返回经纬度
georadius china:city 110  30 1000 km withdist  count 2#限制数量
georediusbymember  china:city  beijing 100 km  #以元素为中心寻找
geohash  #返回一个或多个元素的geohash表示  11个字符的字符串

GEO 底层的实现原理就是zset,可以使用zset命令来操作geo

zrange  china:city  0 -1  #查看全部元素
zrem  china:city  beijing #删除

Hyperloglog

什么是基数

一组数中不重复的元素

Redis Hyperloglog 基数统计的算法

优点:占用的内存是固定的,2^64不同的元素的技术,只需要12KB内存,如果要从内存角度的话Hyperloglog首选

允许出错

pfadd mykey a b c d f   #添加
pfcount  mykey     #统计
pfmerge  mykey3 mykey mykey2  #合并mykey,mykey2 到mykey3
pfcount   #统计基数的数目

Bitmap

位存储

统计用户信息

活跃,不活跃,登陆,不登录,打卡,365打卡

bitmap 位图,数据结构,都是操作二进制位来记录,就只有0和1两个状态

setbit  setbit sign 0 1
setbit  setbit sign 3 1
getbit sign 3

#统计操作
bitcount  sign    #统计1的数

基本事务操作

Redis事务本质:一组命令的集合!一个事务的所有命令都会被序列化,在事务执行过程中,会按照顺序执行

一次性/顺序性/排他性:执行一系列命令-------队列--set --set --set ----执行

Redis事务没有隔离级别的概念

所有的命令在事务中,并没有直接被执行,只有发起命令的时候才会执行

Redis单条命令是保证原子性的,但是事务不保证原子性

redis的事务:

  • 开启事务(multi)
  • 命令入队()
  • 执行事务(exec)

正常执行事务

multi  #开启事务
set k1 v1 #命令入队
set k2 v2 #命令入队
exec  #执行事务

#需要重新开启事务
multi
set  k1 v3
set k2 v3
discard #取消事务   命令都不执行

编译型异常(代码有问题,命令有错),都不执行

运行时异常(1/0) 如果事务队列中存在语法性,那么执行命令的时候,其他命令可以正常执行,错误命令抛出异常

乐观锁

悲观锁:无论做什么都加锁

乐观锁:认为不会上锁,更新数据判断是否有人修改

  • 获取version
  • 更新的时候比较version

监控:watch

set money  100
set out 0
watch money  #监视money对象
multi         #事物正常结束,数据期间没有发生变动,这个时候就正常执行成功
decrby money 20
incrby out 20
exec    #执行之前,另外一个线程,修改了我们的值,这个时候就会导致事务执行失败
unwatch   #修改失败,获取最新值就好
watch money
#再次开启事务操作

测试多线程修改值,监视失败,使用watch可以当作redis的乐观锁操作

Redis.conf详解

Redis持久化

Redis是内存数据库,如果不讲内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失,所以Redis提供了持久化的功能

RDB

在指定的时间间隔内将内存中的数据集快照写入磁盘,Snapshot快照,他恢复时是将快照直接读到内存

Redis会单独创建fork一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件,整个过程中,主进程是不进行IO操作的,这就确保了极高的性能,

RDB方式比AOF方式更加高效,缺点是最后一次持久化后的数据可能丢失

默认的就是RDB,一般情况下不需要修改这个配置

rdb保存的文件是dump.rdb

#redis.conf
save 60 5  #60秒内修改5次触发
dbfilename  dump.rdb

触发机制

  • save的规则满足的情况下,自动触发rdb规则

  • 执行flushall命令,也会触发rbd规则

  • 退出redis,也会产生rdb文件

    备份就自动生成一个rdb文件

    只需要将rdb文件放在redis启动目录就可以,redis启动的时候会自动检查dump.rdb,恢复其中的数据

    查看需要存在的位置

    config get dir  
    #默认的配置够用
    

    优点:

    适合大规模的数据恢复

    如果对数据的完整性要求不高

    缺点

    需要一定时间间隔来操作,如果redis意外宕机了,这个最后一次修改的数据就没有了

    fork进程的时候,会占用一定的内容空间

AOF(append only file)

将我们的所有命令都记录下来,恢复的时候把这个文件全部执行一遍

以日志的形式来记录每个写操作,将redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,redis重启的时候根据日志的内容将写指令从前到后执行一次以完成数据的恢复工作

AOF保存的是appendonly.aof文件

append #配置
appendonly no  #默认不开启,需要手动进行配置,改为yes
appendfilename appendonly.aof
appendfsync everysec  
appendfsync always
appendfsync no  
##rewrite
重写规则,默认大于64Mb
fork一个新的进程将文件重写

如果这个aof文件有错误,redis启动不了,需要修复aof文件

redis给我们提供了一个工具,redis-check-aof --fix appendonly.aof

优点:

  • 每一次修改都同步,文件的完整性会更好
  • 每秒同步一次,可能会丢失一秒的数据
  • 从不同步,效率最高的

缺点:

  • 相对于数据文件来说,aof远远大于rdb,修复的速度也比rdb慢
  • aof运行效率也比rdb慢,所以我们redis默认的配置就是rdb持久化

扩展:

  • 只做缓存,不需要持久化
  • 同时开启两种,默认先载入aof文件恢复原始数据
  • 性能:rdb文件用作后备用途,建议只在slave上持久化文件,15分钟一次

Redis发布订阅

发布订阅(pub/sub)是一种消息通信模式:发送者发送消息,订阅者接收消息

  • 消息发布者
  • 频道
  • 消息订阅者
#订阅端
psubscribe  #接收多个
subscribe  channel  #订阅频道  等待读取信息
1)message
2)channel
3)"dddf"

#发送端
publish channel "dddf"

使用场景:

  • 实时消息系统
  • 实时聊天
  • 订阅关注系统

Redis主从复制

主从复制:是将一台redis服务器的数据复制到其他的redis服务器。前者称为主节点(master/leader),后者称为从节点(slave/follower)

数据的复制是单向的,只能由主节点到从节点,Master以写为主,Slave以读为主

默认情况下,每台服务器都是主节点,且一个主节点可以有多个从节点,但一个从节点只能有一个主节点

主从复制的作用:

  • 数据冗余:主从复制实现了数据的热备份,是持久化的一种数据冗余方式
  • 故障恢复:当主节点出现问题,可以由从节点提供服务,实现快速的故障恢复,实际上是一种服务的冗余
  • 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,从节点提供读服务(即写redis数据时应用连接主节点,读redis数据时应用连接从节点),分担服务器负载,尤其是在写少读多的场景下,通过多个从节点分担负载,可以大大提高redis服务器的并发量
  • 高可用(集群)基石:主从复制还是哨兵和集群能够实施的基础,因此说主从复制是redis高可用的基础

一般配置一主二从

单机会宕机

原因:

  • 结构上,单个redis服务器会发生单点故障,一台服务器需要处理所有的请求负载,压力较大
  • 容量上,单个redis服务器内存容量有限

环境配置

只配置从库不用配置主库

info replication  #查看当前库的信息
redis-server kconfig/redis80.conf  #开启服务

复制三个配置文件,然后修改对应的信息

  • 端口
  • pid名字
  • log文件名字
  • dump.rdb名字

修改完毕之后,启动服务

一主二从

默认每台服务器都是主节点:一般只用配置从机

slaveof 127.0.0.1 6379
info replication
命令是暂时的,进配置文件修改时永久的

主机可以写,从机不能写,只能读

主机断开连接,从机依旧连接到主机,但是没有写操作,这个时候,主机如果回来了,从机依旧可以直接获取到主机写的信息

如果是使用命令行来配置的主从,这个时候如果重启了,就会变回主机,只要变为从机,立马就会从主机中获取值

slave启动成功连接到master后会发送一个sync同步命令

Master接到命令后,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,并完成一次完全同步

全量复制:slave服务在接收到数据库文件数据后,将其存盘并加载到内存中

增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步

但是只要是重新连接,一次完全同步(全量复制)将被自动执行,数据一定可以在从机中看到

层层连接

手动配置

命令方式
slaveof no one #主动把自己选为主节点,老大修复了,重新连接

哨兵模式(自动选举)

哨兵模式是一种特殊的模式,哨兵是一个独立的进车改,作为进程,他会独立运行,其原理是哨兵通过发送命令,等待redis服务器响应,从而监控运行的多个redis实例

防止一个哨兵出现问题,配置多个哨兵,多个哨兵之间还会进行监控

哨兵作用:

  • 通过发送命令,让redis服务器返回监控其运行状态,包括主服务器和从服务器
  • 当哨兵监测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让他们切换主机

主观下线

投票

客观下线

如果主机回来了,只能归并到新的主机下,当作从机,这就是哨兵模式的规则

优点:

  • 哨兵集群,基于主从复制,所有主从配置优点都有
  • 主从可以切换,故障可以转移,系统的可用性更好
  • 哨兵模式就是主从模式的升级,手动到自动

缺点:

  • redis不好在线扩容的,集群容量一旦到达上限,在线扩容就十分麻烦
  • 实现哨兵模式的配置其实是很麻烦,里面有很多选择

缓存穿透和雪崩

服务的高可用问题

缓存穿透(查不到)

查询数据,缓存没有命中,都去请求数据库,给数据库很大压力,出现缓存穿透

解决方案:

  • 布隆过滤器
    • 一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层系统的欻性能压力

缓存空对象

? 出现的问题

  • 空值缓存起来,需要更多空间
  • 即使对空值设置了过期时间,还是会在缓存层和存储层的数据会有一段时间窗口的不一致

缓存击穿

微博服务器宕机()

指一个key非常热点,在不停的访问,当key失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,数据库压力瞬间过大

解决方案:

  • 设置热点数据永不过期

  • 加互斥锁

    • 分布式锁,使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可,这种方式将高并发的压力转移到了分布式锁,因此对分布式锁的考验很大

缓存雪崩

指在某一个时间段,缓存集中过期失效

比如抢购的时候

停掉一些服务,保证主要的服务可用

解决方案:

  • redis高可用(异地多活),增加redis服务器,搭建集群
  • 限流降级,通过加锁或队列来控制数据库写缓存的线程数量
  • 数据预热,在正式部署之前,把可能数据先预先访问一遍,加载到缓存,设置不同的过期时间

Redis 学习

原文:https://www.cnblogs.com/uxquan/p/13737435.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!