【redis笔记】redis应用

redis应用

redis 发布订阅

redis客户端可以订阅任意数量的频道

订阅方式

subscribe channel1 – 订阅了channel1频道

发布方式

订阅了之后,可以在任意客户端发布消息到指定channel
publish channel1 hello – 往channel发布hello,会返回订阅channel1的数量

redis bitmaps数据类型

redis提供了bitmaps以便对位进行操作,常用于签到、网站用户访问统计(用户id为32或64位,当天访问为1,不访问为0)等场景,命令格式如下:
setbit key offset value 其中,value值为0或1,offset为位的偏移量,从0开始
getbit key offset 获取key的offset位值
bitcount key [start end]获得key中start到end字节中存在bit为1的数量
bitop and/or/not/xor destkey key… 用来做多个bitmaps的复合操作,按位与或非并将结果保存在destkey中

redis hyperLogLog数据类型

常用与实际工作中统计uv,独立ip数,搜索记录数等需要去重和计数的集合中求不重复元素个数的基数问题。
虽然我们像mysql,redis中都有一些方案,像mysql中的distinct count,redis中的hash,set,bitmaps都可以用来处理这类问题,但在数据量很大的时候,存在内存空间问题。HyperLogLog的优势是在数据量非常大时,计算基数所需的空间是很小的,比较固定的。12KB的内存,可以计算接近2^64个元素基数
常用命令有:
pfadd key “xxx” 加入数据xxx,如果已经存在返回0,成功返回1
pfcount key 统计key的数量
pfmerge destkey srckey1 … 将多个key的数据合并到destkey中

geospetial数据类型

redis3.2以上的版本提供了geo的支持,包含了经纬度设置、查询、范围查询、距离查询、经纬度hash等操作。

常用命令

geoadd key latitude longtitude member … 添加一个或多个坐标集合,如geoadd Chinacity 122.34 24.54 xy_1 133.1 56.2 xy_2
有效精度在-180到180之间,有效维度从-85.05112878到85.05112878之间。坐标超出范围返回错误。
geopos key member 获得key集合中member的经纬度
geodist key member1 member [m/km/ft/mi]获得key集合中member1坐标和member2坐标的直线距离,默认距离以m(米为单位)
georadius key latitude longtitude radius [m|km|ft|mi] 以给定坐标为中心,找出某一半径内的元素,半径单位也可以选,默认米

redis事务

redis事务是一个单独的隔离操作,事务中所有命令都会序列化、按顺序地执行,事务在执行过程中,不会被其他客户端发来的命令请求打断,redis事务的作用主要是串联多个命令防止被其他命令插队。

redis事务命令

从输入Multi开始,输入的命令都会依次进入命令队列,但不会被执行,直到输入Exec,redis会将输入的命令依次执行,如果我们在输入命令的过程中,有些命令不想要了,可以用discard命令来丢弃。
如下为示例
在这里插入图片描述

redis事务错误处理

组队的时候如果有命令错误,最终都不会执行。组队命令没问题,执行的过程中有部分命令失败,有错误的命令执行失败,其他命令正常执行。

redis事务冲突与解决机制

为了解决多个请求同时操作同一个值的场景下,我们在编写redis事务操作时,可能认为某个值是A,但实际上在事务入队还没执行之前已经变成了B,如果我们继续按A去操作可能出现问题,从而出现一些非预期的结果(当然也可能没问题,但不可控)。至于像很多地方说的冲突就是10000块的账户减8000,减1000,减5000的问题,如果我就是允许它能为负值,那也没什么问题,我们冲突的关键在与人工判断的部分,我们在执行账户减少的时候我们的当前值是什么,能不能减,而不是只要有同时操作就会冲突。可以通过加锁的方式解决冲突。

悲观锁

每次操作数据都加锁,其他人想访问该数据需要等到锁被释放。传统的关系型数据库大多是这类,如表锁、行锁,都是在操作之前上锁。悲观锁的缺点在于效率比较低。

乐观锁

拿数据的时候不会上锁,在更新的时候判断别人是否有更新,如果有更新,版本不匹配,则不执行更新。判断是否有更新一般使用check-and-set 版本号机制。多用于读数据多的场景。像抢票的时候,我们一般只有一个人成功,其他人都会失败。

案例

在执行multi之前,先使用watch key [keyn…]监视一个或多个需要关注的key,在事务执行前监视的key被改动,事务将被打断。如果不再需要监视了可以在事务中用unwatch取消,如果exec或discard已经执行过了,那就不需要执行unwatch了。
在这里插入图片描述

redis事务的三个特性

  • 单独的隔离操作–事务中所有命令都会序列化、按顺序地执行,不会被其他客户端发来的请求打断。
  • 没有隔离级别–队列中的命令没有提交之前都不会被实际执行
  • 不保证原子性–事务中如果有一条命令失败,其他命令仍然会被执行,没有回滚

多个事务操作同一个变量的解决方案

如果我们在使用事务时,希望能同时对一个变量操作,不要因为一个事务中断另一个事务的操作,比如我们有500张优惠券,希望在还没抢完的情况下,如果有用户同时抢,那么两个都可以抢到,而不是一个的事务影响到另一个,这时可以使用Lua脚本来解决。
一般一些redis客户端会提供lua脚本加载的接口,像jedis,redission中都有。

redis持久化

redis提供了两种持久化方式:RDB(redis database)和AOF(append of file)

RDB

RDB方式是在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的snapshot快照,它恢复时是将快照文件直接读到内存里。比如每过10秒将当前时间点的数据库中的数据写入磁盘。redis在操作的过程中会fork出一个子进程来执行持久化操作,在这个过程中会先写入到一个临时文件,等到持久化过程结束,再将临时文件替换上次保存好的持久化文件。整个过程中主进程是不进行任何IO操作的,因此性能比较高,如果需要大规模的数据恢复,且数据恢复的完整性要求不高,RDB方式要比AOF方式要高效,缺点是可能最后一次持久化的数据会丢失,因为间隔时间可能还没到但服务其挂了。
可以通过修改redis配置来设置RDB的持久化,可以配置成xx时间内有多少个key值变化就执行持久化。
redis启动时会自动加载dump出来的rdb文件
rdb默认开启

AOF

以日志的形式来记录每个写操作,以追加的方式写,redis启动的时候会执行一遍所有的写操作来恢复数据
AOF默认不开启,可以通过修改配置中的appendonly项修改为yes,RDB和AOF同时开启redis优先使用AOF.
redis AOF有异常恢复机制,可以通过/usr/local/bin/redis-check-aof --fix appendonly.aof来恢复
AOF有三种同步方式:
appendfsync always – 总是同步,每次写操作都马上同步到日志,这样保存的日志是最完整的,但同时也会导致性能下降
appendfsync everysec – 每秒同步一次,最多丢失前一秒操作的数据
appendfsync no – 不主动同步,由操作系统来决定什么时候同步

rewrite压缩

为了节省空间,redis有rewrite机制将对同一个元素的多次操作,只记录最终影响的那一次操作,当AOF大小超过阈值后就会启动该机制。也可以使用bgrewriteaof命令重写。当aof文件大于2倍basesize且当前大小大于64MB的情况下,redis会对aof文件重写。重写也是会fork一个子进程,产生一个临时文件,在写完后再替换原aof文件

如何选择持久化方案

如果对数据不敏感,可以用单独用rdb,不建议单独用aof,可能有bug,只做纯缓存用的话可以不用开启

redis应用问题缓存穿透

大量的请求访问redis时,如果较多请求在redis中不存在,频繁地直接查询数据库或访问后端服务,导致数据库或后端服务压力较大而崩溃。
解决方案:

  • 对空值缓存 如果一个查询的返回数据为空,我们仍然对这个空结果做缓存,但需要对这个空值设置过期时间,一般来说过期时间不超过5分钟,但这个方案对攻击的随机性不太适用
  • 设置可访问名单,使用bitmaps定义一个可以访问的名单,名单id作为bitmaps的偏移量,每次均将query和bitmaps里面的id进行对比,效率较低
  • 布隆过滤器,底层是hash加bitmaps,但存在误识别率
  • 实时监控,如果redis的命中率降低,需要排查访问对象

redis缓存击穿

数据库访问压力瞬时增大,但redis中的key并没有出现大量过期,redis也在正常运行,可能原因是:
(1)redis中某个key刚好过期了但大量的访问都涉及到该key(热key)。
(2)在更新redis中数据时,delete老key时请求刚好并发量很大
解决方案:

  • 预先设置热门数据,在高峰访问前,预先存入redis,并加大key的时长或者不设置失效时间
  • 实时监控哪些数据热门,及时调整
  • 互斥更新,双检加锁 在缓存失效时(拿到值为空时),不做任何处理的情况下,我们都会查询数据库来,然后重新设置缓存,这样对数据库的压力就会很大,我们可以先设置一个排他锁,如果排他锁已经存在,说明已经有别的线程在设置数据库更新缓存,如果成功我们再更新缓存,再释放锁。在获取到锁的时候再次查询redis,判断有没有其他用户已经更新过缓存了。

缓存雪崩

在极少时间段内,查询大量key过期的场景,会导致大量的请求直接打到mysql,导致服务器崩溃。
解决方案:

  • 构建多级缓存:nginx缓存+redis缓存+其他缓存
  • 使用锁或队列避免失效时大量并发请求落到底层存储系统上,不适用于高并发
  • 设置过期标志(提前值),过期触发另外的线程去更新该key
  • 分散缓存失效时间,避免key的集体过期

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/226286.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

class036 二叉树高频题目-上-不含树型dp【算法】

class036 二叉树高频题目-上-不含树型dp code1 102. 二叉树的层序遍历 // 二叉树的层序遍历 // 测试链接 : https://leetcode.cn/problems/binary-tree-level-order-traversal/ code1 普通bfs code2 一次操作一层 package class036;import java.util.ArrayList; import java…

9. 使用Pthreads实现线程池(一)

背景 多线程的一个典型应用场景就是服务器的并发处理,如下图所示,多名用户向服务器发出数据操作的请求。为了提高并发性,我们可以在每收到一个用户请求时就创建一个线程处理相关操作。这种操作在请求数量较少时没有什么问题,但在请求数量很多时你会发现线程的创建和销毁所占…

绑定域名简单教程

📑打牌 : da pai ge的个人主页 🌤️个人专栏 : da pai ge的博客专栏 ☁️宝剑锋从磨砺出,梅花香自苦寒来 🌤️安装Nginx环境 &…

第七次作业

1, 给定一个包含n1个整数的数组nums,其数字在1到n之间(包含1和n),可知至少存在一个重复的整数,假设只有一个重复的整数,请找出这个重复的数 arr input("") num [int(n) for n in arr.split()]…

mysql 5.7 Unknown column ‘password‘ in ‘field list‘

问题现象: 执行sql : select user,host,password from user;时提示 ERROR 1054(42S22):Unknown column password in field list 现象如下图所示: mysql 5.7开始 密码字段用:authentication_string

http接口自动化测试框架实现

一、测试需求描述 对服务后台一系列的http接口功能测试。 输入:根据接口描述构造不同的参数输入值 输出:XML文件 eg:http://xxx.com/xxx_product/test/content_book_list.jsp?listid1 二、实现方法 1、选用Python脚本来驱动测试 2、采用Excel表格…

【hacker送书第10期】AI时代系列丛书(五选一)

AI时代系列丛书 AI时代程序员开发之道✨内容简介参与方式 AI时代项目经理成长之道✨内容简介参与方式 AI时代架构师修炼之道✨内容简介参与方式 AI时代产品经理升级之道✨内容简介参与方式 AI时代Python量化交易实战✨内容简介参与方式 AI时代程序员开发之道✨ 内容简介 本书是…

zabbix配置snmp trap--使用snmptrapd和Bash接收器--图文教程

1.前言 我的zabbix的版本是5.0版本,5.0的官方文档没有使用bash接收器的示例,6.0的官方文档有使用bash接收器的示例,但是,下载文件的链接失效?! 这里讲解zabbix-server端配置和zabbix web端配置 2.zabbix-…

好用免费的AI换脸5个工具

在当今社会的发展中,人工智能(Artificial Intelligence, AI)扮演着关键的角色,其应用领域不断扩展。作为AI的一个分支,换脸技术近年来备受欢迎。这项技术使得将一个人的面部特征迁移到另一个人的照片或视频成为可能。除…

链式二叉树的创建及遍历(数据结构实训)

题目: 链式二叉树的创建及遍历 描述: 树的遍历有先序遍历、中序遍历和后序遍历。先序遍历的操作定义是先访问根结点,然后访问左子树,最后访问右子树。中序遍历的操作定义是先访问左子树,然后访问根,最后访问…

Ubuntu宝塔面板本地部署轻论坛系统HadSky并远程访问

文章目录 前言1. 网站搭建1.1 网页下载和安装1.2 网页测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道(云端设置)2.3 Cpolar稳定隧道(本地设置)2.4 公网访问测试 总结 前言 经过多年的基础…

【python、opencv】opencv仿射变换原理及代码实现

opencv仿射变换原理 仿射变换是opencv的基本知识点,主要目的是将原始图片经过仿射变换矩阵,平移、缩放、旋转成目标图像。用数学公式表示就是坐标转换。 其中x,y是原始图像坐标,u,v是变换后的图像坐标。将公式转换为…

深入Os--动态链接

1.动态链接库的使用 动态库支持以两种模式使用,一种模式下,在程序加载运行时,完成动态链接。一种模式下,在程序运行中,完成动态链接。 1.1.程序加载运行时完成动态链接 我们通过一个实例介绍程序加载运行时&#xff0c…

深入理解Dubbo-1.初识Dubbo

👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码、Kafka原理、分布式技术原理🔥如果感觉博主的文章还不错的话&#xff…

12.7作业

1. #include "mywidget.h"MyWidget::MyWidget(QWidget *parent): QWidget(parent) {//***********窗口相关设置***********//设置窗体大小this->resize(540,410);this->setFixedSize(540,410);//取消菜单栏this->setWindowFlag(Qt::FramelessWindowHint);/…

【数据库】基于时间戳的并发访问控制,乐观模式,时间戳替代形式及存在的问题,与封锁模式的对比

使用时间戳的并发控制 ​专栏内容: 手写数据库toadb 本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。 本专栏会…

MySQL之binlog文件过多处理方法

背景 MySQL由于大量读写,导致binlog文件特别的多。从而导致服务器disk空间不足问题。 先备份binlog文件 tar -zcvf mysql.tar.gz mysql/data/mysql-bin.00* 修改MySQL配置 binlog过期时间 show variables like expire_logs_days; 这里 0 表示 永不过期 如果为 n…

LeedCode刷题---双指针问题(二)

顾得泉:个人主页 个人专栏:《Linux操作系统》 《C/C》 《LeedCode刷题》 键盘敲烂,年薪百万! 一、盛水最多的容器 题目链接:盛最多水的容器 题目描述 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xf…

Nacos下载、启动与使用的保姆级教程!

nacos下载及启动 nacos下载 首先打开nacos官方仓库链接。Nacos发布版本仓库。 点击Tags按钮找到nacos的历史发布的所有版本,点击download。 然后选择需要的下载即可。 后缀为.tar.gz为linux系统上运行的压缩包 后缀为.zip为windows系统上运行的压缩包 zip格式的…

vivado时序方法检查5

TIMING-14 &#xff1a; 时钟树上的 LUT 在时钟树上发现 LUT <cell_name> 。不建议在时钟路径上包含 LUT 单元。 描述 时钟路径上的 LUT 可能导致偏差过大 &#xff0c; 因为时钟必须在穿过互连结构的常规布线资源上进行布线。除偏差过大外 &#xff0c; 这些路径更…