Redis__高级

1、布隆过滤器

1.1、布隆过滤器是什么?(判断某个key一定不存在)
  • 本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构
  • 特点是高效地插入和查询,可以用来告诉你 “某样东西一定不存在或者可能存在”。
  • 相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。

使用:

  • 布隆过滤器在NoSQL数据库领域中应用的非常广泛
  • 当用户来查询某一个row时,可以先通过内存中的布隆过滤器过滤掉大量不存在的row请求,然后去再磁盘进行查询
  • 布隆过滤器说某个值不存在时,那肯定就是不存在,可以显著降低数据库IO请求数量
1.2、应用场景

1)场景1(给用户推荐新闻)

  • 当用户看过的新闻,肯定会被过滤掉,对于没有看多的新闻,可能会过滤极少的一部分(误判)。这样可以完全保证推送给用户的新闻都是无重复的。

2)场景2(爬虫url去重)

  1. 在爬虫系统中,我们需要对url去重,已经爬取的页面不再爬取
  2. 当url高达几千万时,如果一个集合去装下这些URL地址非常浪费空间
  3. 使用布隆过滤器可以大幅降低去重存储消耗,只不过也会使爬虫系统错过少量页面
1.3、布隆过滤器原理
  • 每个布隆过滤器对应到Redis的数据结构是一个大型的数组和几个不一样的无偏hash函数
  • 如下图:f、g、h就是这样的hash函数(无偏差指让hash映射到数组的位置比较随机)

添加:值到布隆过滤器

  • 1)向布隆过滤器添加key,会使用 f、g、h hash函数对key算出一个整数索引,然后对长度取余
  • 2)每个hash函数都会算出一个不同的位置,把算出的位置都设置成1就完成了布隆过滤器添加过程

查询:布隆过滤器值

  • 1)当查询某个key时,先用hash函数算出一个整数索引,然后对长度取余
  • 2)当你有一个不为1时肯定不存在这个key,当全部都为1时可能有这个key
  • 3)这样内存中的布隆过滤器过滤掉大量不存在的row请求,然后去再磁盘进行查询,减少IO操作

删除:不支持

  • 1)目前我们知道布隆过滤器可以支持 add 和 isExist 操作
  • 2)如何解决这个问题,答案是计数删除,但是计数删除需要存储一个数值,而不是原先的 bit 位,会增大占用的内存大小。
  • 3)增加一个值就是将对应索引槽上存储的值加一,删除则是减一,判断是否存在则是看值是否大于0。
    在这里插入图片描述

2、redis事物

2.1、redis事物介绍
  1. redis事物是可以一次执行多个命令,本质是一组命令的集合。
  2. 一个事务中的所有命令都会序列化,按顺序串行化的执行而不会被其他命令插入
    作用:一个队列中,一次性、顺序性、排他性的执行一系列命令
2.2、redis事物基本使用
  • 下面指令演示了一个完整的事物过程,所有指令在exec前不执行,而是缓存在服务器的一个事物队列中
  • 服务器一旦收到exec指令才开始执行事物队列,执行完毕后一次性返回所有结果
  • 因为redis是单线程的,所以不必担心自己在执行队列是被打断,可以保证这样的“原子性”

注:redis事物在遇到指令失败后,后面的指令会继续执行

  • mysql的rollback与redis的discard的区别:
    • mysql回滚为sql全部成功才执行,一条sql失败则全部失败,执行rollback后所有语句造成的影响消失
    • redis的discard只是结束本次事务,正确命令造成的影响仍然还在.
# Multi 命令用于标记一个事务块的开始事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令原子性( atomic )地执行
> multi(开始一个redis事物)
incr books
incr books
> exec (执行事物)
> discard (丢弃事物)
#在命令行测试redis事物
[root@redis ~]# redis-cli
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set test 123
QUEUED
127.0.0.1:6379> exec
1) OK
127.0.0.1:6379> get test
"123"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set test 456
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get test
"123"
127.0.0.1:6379> 
#	使用python测试redis事物
#定义ip
host = 'localhost'
#建立服务连接
r = redis.Redis(host=host)
pipe = r.pipeline()
#开启事务
pipe.multi()
#存储子命令
pipe.set('key2', 4)
#执行事务
pipe.execute()
print(r.get('key2'))

3、watch指令

实质:WATCH 只会在数据被其他客户端抢先修改了的情况下通知执行命令的这个客户端(通过 WatchError 异常)但不会阻止其他客户端对数据的修改

  • watch其实就是redis提供的一种乐观锁,可以解决并发修改问题
  • watch会在事物开始前盯住一个或多个关键变量,当服务器收到exec指令要顺序执行缓存中的事物队列时
  • redis会检查关键变量自watch后是否被修改(包括当前事物所在的客户端)
  • 如果关键变量被人改动过,exec指令就会返回null回复告知客户端事物执行失败,这个时候客户端会选择重试

:redis禁用在multi和exec之间执行watch指令,必须在multi之前盯住关键变量,否则会出错

### 如何配置和使用 REDIS_DATABASE 环境变量 #### 1. 配置 REDIS_DATABASE 环境变量 在 Linux 和 macOS 中,可以通过编辑 `~/.bash_profile` 文件来设置环境变量。以下是具体操作: ```bash export REDIS_DATABASE=5 ``` 保存并关闭文件后,执行以下命令使更改生效: ```bash source ~/.bash_profile ``` 对于 Windows 系统,则可以按照以下步骤完成环境变量的添加: - 打开运行窗口(Win + R),输入 `rundll32 sysdm.cpl,EditEnvironmentVariables` 并回车。 - 在弹出的“系统属性”对话框中找到“高级”选项卡下的“环境变量”按钮点击进入。 - 添加一个新的系统变量名为 `REDIS_DATABASE`,其值设为你希望使用的数据库编号。 以上方法能够确保程序运行时可以从操作系统层面访问到这个自定义的环境变量[^3]。 #### 2. 使用 REDIS_DATABASE 环境变量 当设置了上述环境变量之后,在实际应用开发过程中就可以利用它动态调整 Redis 数据库的选择逻辑而无需硬编码固定数值了。例如在一个典型的 Spring Boot 应用里,我们可能这样定义我们的数据源连接信息: ```yaml spring: redis: database: ${REDIS_DATABASE:0} host: localhost port: 6379 ``` 这里的 `${REDIS_DATABASE:0}` 表达式的含义是从外部环境中寻找名为 `REDIS_DATABASE` 的键对应的值作为最终的实际使用的数据库号;如果找到这样的键则会退回到默认值 `0` 上面去处理请求事务[^2]。 另外值得注意的是某些特定工具像 Prometheus 的 exporter 工具也支持类似的机制通过命令行参数或者是额外声明好的全局范围内的 env var 来控制行为模式。比如针对 redis_exporter 而言就有专门用于激活包含系统级别指标收集功能开关的一个叫做 `-include-system-metrics` 参数或者对应名称为 `REDIS_EXPORTER_INCL_SYSTEM_METRICS=true` 这样的 ENV VAR 设置方式可供选择[^4]。 因此无论是在脚本编写还是框架集成当中合理运用好这些灵活可变的因素都可以极大地提升项目的适应性和扩展能力。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值