redis笔记

java中的i++不是原子操作
i = 0 ,两个线程分别对i进行i++ 100次,值为(2~200)
极端情况:线程2在开始取到i值为0,在线程2第一次执行赋值操作期间线程1执行了99次,当线程2赋值后i的值重新变为1;同理,线程1最后一次操作取到i值为1,在线程1执行赋值操作期间,线程2执行了剩下的99次,使得i大于100,但由于线程1第100次操作取到i等于1,并且赋值操作在线程2执行完毕后执行,所以极端情况最小值为2
在这里插入图片描述

1、常用命令

  • keys * 查看当前数据库全部键
  • select 切换数据库
  • exists < key > 判断某个key是否存在
  • type < key > 查看当前key的类型
  • del < key > 删除指定的key数据
  • unlink < key > 根据vlaue选择非阻塞删除(异步删除)
  • expire < key > < 10 > 10秒钟(设置过期时间)
  • ttl < key > 查看key还有多久过期(单位秒,-1永不过期,-2已过期)
  • dbsize 查看当前数据库的key数量
  • flushdb 清空当前库
  • flushall 清空全部库

2、常用数据类型

1、string类型

1、命令
  • get < key > 获取key对应的vlaue
  • append < key > < value > 追加字符串
  • strlen < key > 获取值的长度
  • setnx < key> < value > 只有在key不存在时设置key的值
  • incr < key > 将key对应的数字value加1 (原子性操作,单线程)
  • decr < key > 将key对应的数字value减1
  • incrby < key > < 值 > 将key对应的数字value加n
  • decrby < key > < 值 > 将key对应的数字value减n
  • mset < key > < 值 > < key > < 值 > 一次设置多个key
  • mget < key > < key > 一次获取多个key的value
  • msetnx < key > < 值 > < key > < 值 > 如果有一个键存在,即全部赋值失败
  • getrange < key > 开始下标 结束下标, 获取value的片段(截取字符串)
  • setrange < key > 开始下标 < 值 > 将value从下标位置开始替换成输入的值
  • setex < key > < 过期时间 > < 值 >
  • getset < key > < 值 > 取出旧值并赋上新值
2、数据结构
  • string数据结构为动态字符串(可变字符串),内部结构与ArrayList类似,采用预分配冗余空间的方式减少内存的频繁分配
  • 分配的空间一般高于实际实际字符串长度,当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次只会增加1M,字符串最大长度512M

2、List类型

底层是个双向列表,可以对两端进行操作。

1、命令
  • lpush / rpush < key > < 值 > < 值 > < 值 > 从左边/右边插入一个或多个值
  • lpop / rpop < key > 从左边/右边pop一个值
  • rpoplpush < key1 > < key2 > 从key1右边pop一个值放到key2左边中
  • lrange < key > 0 -1 查看全部值
  • lindex < key > < index> 从key中取出第index个元素
  • llen < key > 获得列表长度
  • linsert k1 < value(列表中的值) > < newvalue > 在k1列表的value前面添加一个值
  • lrem < key > < count> < value > 删除key列表count个value, 从左开始
  • lset < key > < index> < value > 将key列表的index位置替换为value
2、数据结构
  • list的数据结构为快速列表 quicklist
  • 在列表元素较少的情况下会使用一块连续的内存存储,这个结构叫ziplist(压缩列表)
  • 元素数量较多时会改成quicklist
  • 普通链表需要附加指针空间,比较浪费空间
  • 满足快速插入删除性能,还不会出现太大的空间冗余

3、Set类型

  • 自动去重,是string类型的无序集合。
  • 底层是一个value为null的hash表
  • 添加、删除、查找时间复杂度为O(1)
1、命令
  • sadd < key > < value > < value > 添加一个set集合
  • smembers < key > 取出key的set集合
  • sismember < key > value 判断key集合是否含有某个值
  • scard < key > 查看key集合元素的个数
  • srem < key > value 删除集合一个或多个元素
  • spop < key > 随机pop一个值
  • srandmember < key > < count > 随机取出count个元素
  • smove < source > < destination > < value > 把集合中的一个值从该集合移动到另一个集合
  • sinter < key > < key > 返回两个集合的交集元素
  • sunion < key > < key > 返回两个集合的并集元素
  • sdiff < key1 > < key2 > 返回key1集合中key2不存在的元素(类似k1 - k2)
2、数据结构
  • set集合数据结构是dict字典
  • 字典用哈希表实现
  • 与java的hashSet结构一样,内部使用hash结构,所有value都指向同一个内部值

4、Hash类型

  • 适合存储对象
1、命令
  • hset < key > < field > < value > 给集合的field赋值
  • hget < key > < field > 向集合取出field 的值
  • hmset < key > < field > < value > < field > < value > < field > < value > 批量设置hash的值
  • hexists < key > < field > 查看哈希表key中是否存在field
  • hkeys < key > 查看哈希表所有的field
  • hvals < key > 查看哈希表所有的value
  • hincrby < key > < field > < increment > 给field增加或减少一个数
  • hsernx < key > < field > < value > field 不存在时可添加
2、数据结构
  • Hash类型对应的数据结构时两种(压缩列表):hashtable(哈希表)
  • 当field - value 长度较短且个数较少时,使用ziplist,否则使用hashtable

5、Zset类型

  • 有序集合
  • 没有重复元素
  • score可重复但value唯一
1、命令
  • zadd < key > < score > < value > < score > < value > 将一个或多个元素及其score值添加到zset中
  • zrange < key > < start > < stop > [WITHSCORES] 返回zset集合, 带WITHSCORES会将score值
  • zrangebyscore < key > < min > < max > [WITHSCORES] 查看score范围的元素(从小到大)
  • zrevrangebyscore < key > < max > < min > [WITHSCORES] 查看score范围的元素(从大到小)
  • zincrby < key > < number > < value > 给value元素 添加 number
  • zrem < key > < value > 删除value 元素及其score值
  • zcount < key > < min > < max > 统计区间元素个数
  • zrank < key > < value > 返回该值在集合的排名,从0开始
2、数据结构
  • 类似与Java的map集合,zset可以给value赋予一个权重score
  • 又类似与java的TreeSet,元素会按权重进行排序,可以得到每个元素的名次,还能通过score的范围获取元素列表
  • hash,关联元素vlaue和权重score,保障元素vlaue的唯一性,可通过vlaue找到对应的score值
  • 跳跃表,跳跃表的目的在于给元素vlaue进行排序,根据score的范围获取元素列表

3、配置文件

4、发布和订阅

  • 是一种消息通信模式
  • 发送者发送消息,订阅者接受消息
  • redis客户端可以订阅任意数量的频道

1、发布订阅命令

  • subscribe < channel > 订阅频道
  • publish < channe > message 向频道发布消息

5、新数据类型

1、Bitmaps类型

  • 如果Bitmaps存储的大多数都为0比较不合适
1、命令
  • setbit < key > < offset > < value > 设置key的第offset 个位的值(从0开始)
  • getbit < key > < offset > 获取key偏移量的值
  • bitcount < key > 统计key被设置为1的bit数
  • bitcount < key > < start > < end > 统计key从start 到end 被设置为1的bit数,可以是负数,表示倒数
  • bitop and < key12 >(user:< and / or / not / xor > :20220101_02) < key1 > < key2 > 计算两个键offset 都为1的个数

2、HyperLogLog类型

1、介绍

用来做基数统计,优点:

  • 输入元素的数量或体积非常非常大时,计算技术所属的空间时固定的,并且是很小的
  • 每个键只需花费12KB内存就可以计算接近2^64个不同元素的基数
  • 只根据输入元素来计算基数,而不会存储输入元素本身,不能返回输入的各个元素

解决基数问题方案:

  • 数据存储在MySQL表中,使用distinct count 计算不重复个数
  • 使用redis提供的hash、set、bitmaps等数据结构处理
  • 数据不断增加导致占用空间越来越大,对于非常大的数据集不合适
2、命令
  • pfadd < key > < value …> 添加指定元素
  • pfcount < key > 计算近似基数
  • pfmerge < destkey > < sourcekey… > 将一个或多个合并后的结果存到destkey中(如:每月用户活跃个数可以使用每天的活跃用户合并计算得到)

3、Geospatial类型

1、介绍
  • 元素为二维坐标,在地图上就是经纬度
  • 提供了经纬度设置,查询,范围查询,距离查询,经纬度Hash等操作
  • 经度范围-180 ~ 180
  • 纬度-85.05112878 ~ 85.05112878
2、命令
  • geoadd < key > < x > < y > < nember > 添加地理位置(坐标和对应的名称)
  • geopos < key > < nember > 获取指定地区的坐标
  • geodist < key > < nember1 > < nember2 > [ m | km | ft | mi ] 获取两个位置之间的直线距离
  • georadius < key > < x > < y > radius [ m | km | ft | mi ] 以给定的经纬为中心,找出某一半径内的元素

6、事务

Redis事务是一个单独的隔离操作

  • 事务中所有命令都会被序列化、按顺序执行
  • 事务执行过程中,不会被其他客户端发送来的命令请求所打断
  • 主要作用是串联多个命令防止别的命令插队

7、乐观锁、悲观锁

  • 乐观锁通过一个版本好控制,防止超卖问题
  • 乐观锁能解决超卖但是会出现库存遗留问题,即同一批请求进来时,拿到的版本号一致,由于有一个指令更新了数据,其他请求版本号不对应导致更新失败。所以会出现数据遗留问题。
  • 乐观锁还会出现连接超时,使用连接池可以解决

8、LUA脚本

  • 类似redis事务,有一定原子性,不会被其他命令插队,可以完成一些redis事务性操作
  • redis2.6版本才能使用
  • 利用lua脚本淘汰用户,解决超卖问题。
  • redis利用单线程的特性,用队列的方式解决多任务并发问题

9、redis持久化

1、RDB

在指定时间间隔内将内存中的数据集快照写入磁盘中

1、备份如何执行
  • redis会单独创建(fork)一个子进程来进行持久化,会将数据写到一个老师文件,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。
  • 主进程不进行RDB的IO操作,确保redis的高性能
  • 若需进行大规模数据恢复且对数据恢复的完整性不是非常敏感,RDB方式要比AOF方式更加高效
2、执行流程

在这里插入图片描述

3、优势
  • 适合大规模的数据恢复
  • 对数据完整性和一致性要求不高更适合使用
  • 节省磁盘空间
  • 恢复速度快
4、劣势
  • 最后一次持久化后的数据可能会丢失
  • Fork的时候,内存的数据被克隆了一份,大致2倍的膨胀性需要考虑
  • redis再fork时使用了写时拷贝技术,但是如果数据量庞大时还是比较消耗性能
  • 备份周期在一定时间间隔做一次备份,如果redis意外down掉的话,就会丢失最后一次快照后所有修改

如:10分钟内至少100个key发生改变,执行Fork
完成一次Fork,但下一次Fork条件还未满足(即10分钟内key发生改变的个数未达到100个),期间redis发生改变的数据将丢失

2、AOF

10、主从复制

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值