Redis笔记(二):Redis客户端的使用&Redis其他功能&持久化的取舍和选择

Redis客户端的使用&Redis其他功能&持久化的取舍和选择

在这里插入图片描述

3. Redis客户端的使用

3-1 课程目录

3-2 Java客户端:Jedis

Jedis是什么
在这里插入图片描述

获取Jedis

Maven依赖

<dependency>
     <groupId>redis.clients</groupId>
     <artifactId>jedis</artifactId>
     <version>2.9.0</version>
     <type>jar</type>
     <scope>compile</scope>
 </dependency>
#1.生成一个Jedis对象,这个对象负责和指定Redis节点进行通信Jedis jedis=new Jedis"127.0.0.1"6379);
#2.jedis执行set操作
jedis.set("hello""world");
#3.jedis执行get操作,value="world"
String value=jedis.get("hello");

构造函数常用参数

Jedis(String host,int port,int connectionTimeout,int soTimeout)
·host:Redis节点的所在机器的IP
·port:Redis节点的端口
·connectionTimeout:客户端连接超时
·soTimeout:客户端读写超时
      //1.生成一个Jedis对象,这个对象负责和指定Redis节点进行通信
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        //1.string
        jedis.set("hello","world");
        //输出结果:world jedis.get("hello");
        // 输出结果:1
        jedis.incr("counter");

        //2.hash
        jedis.hset("myhash","f1","v1");
        jedis.hset("myhash","f2","v2");
        //输出结果:{f1=v1,f2=v2}
        jedis.hgetAll("myhash");

        //3.list 
        jedis.rpush("mylist","1");
        jedis.rpush("mylist","2");
        jedis.rpush("mylist","3");
        ///输出结果:[1,2,3]
        jedis.lrange("mylist",0,-1);

        //4.set 
        jedis.sadd("myset","a");
        jedis.sadd("myset","b");
        jedis.sadd("myset","a");
        //输出结果:[b,a]
        jedis.smembers("myset");

        //5.zset 
        jedis.zadd("myzset",99,"tom");
        jedis.zadd("myzset",66,"peter");
        jedis.zadd("myzset",33,"james");
        //输出结果:[["james"],33.0],[["peter"],66.0],["tom"],99.0]]
        jedis.zrangeWithScores("myzset",0,-1);
Jedis连接池使用

◆Jedis直连
在这里插入图片描述
◆Jedis连接池
在这里插入图片描述
◆方案对比
在这里插入图片描述
◆JedisPool使用

public void useJedisPool(){
        //初始化Jedis连接池,通常来讲JedisPool是单例的。
        GenericObjectPoolConfig poolConfig=new GenericObjectPoolConfig();
        JedisPool jedisPool =new JedisPool(poolConfig,"127.0.0.1",6379);

        Jedis jedis = null;
        try {
        //1.从连接池获取jedis对象
            jedis = jedisPool.getResource());
            //2.执行操作
            jedis.set("hello","world");
        } catch(Exception e){
            e.printStackTrace();
        }finally{
            if(jedis!=null);
            //如果使用JedisPool,close操作不是关闭连接,代表归还连接池jedis.close0;
        }
    }
    

4.瑞士军刀Redis其他功能

除了5种数据结构外,Redis还提供了诸如慢查询、Pipeline、Bitmap、HyperLogLog、发布订阅、GEO等附加功能,在这些功能的帮助下,Redis的应用场景更加丰富。

4-1 课程目录

◆慢查询◆Bitmap
◆pipeline◆HyperLogLog
◆发布订阅◆GEO

4-2 慢查询

◆生命周期

在这里插入图片描述

◆两个配置

slowlog-max-len:但时间达到slowlog-log-slower-than=10000 之后将会认定为慢查询,随后会进入 长度为slowlog-max-len的队列
在这里插入图片描述
slowlog-log-slower-than: 记录为慢查询的阈值

  1. 慢查询阀值(单位:微秒)
  2. slowlog-log-slower-than=0,记录所有命令
  3. slowlog-log-slower-than<0,不记录任何命令。

配置方法

  1. 默认值
    config get slowlog-max-len=128
    config get slowlog-log-slower-than=10000
  2. 修改配置文件重启
  3. 动态配置
    config set slowlog-max-len 1000
    config set slowlog-log-slower-than 1000
◆三个命令
1.slowlog get[n]:获取慢查询队列
2.slowlog len:获取慢查询队列长度
3.slowlog reset:清空慢查询队列
◆运维经验
  1. slowlog-max-len不要设置过大,默认10ms,通常设置1ms
  2. slowlog-log-slower-than不要设置过小,通常设置1000左右。
  3. 理解命令生命周期。
  4. 定期持久化慢查询。

4-3 pipeline

◆什么流水线

在这里插入图片描述
在这里插入图片描述
使用流水线大大减少网络开销
在这里插入图片描述
流水线的作用
在这里插入图片描述
两点注意
1.Redis的命令时间是微秒级别(所以速度的瓶颈在网络)。
2.pipeline每次条数要控制(网络)。
在这里插入图片描述

◆客户端实现
Jedis jedis =new Jedis("127.0.0.1",6379);
        for(int i=0;i<100;i++){
            Pipeline pipeline=jedis.pipelined();
            for(int j=i*100; j<(i+1)*100; j++){
                pipeline.hset("useHashKey:"+j,"field"+j,"value"+j);
                pipeline.syncAndReturnAll();
            }
        }
◆与原生操作(M命令)对比

在这里插入图片描述
Pipeline会被拆分 但依然会保证它的原子性
在这里插入图片描述

◆使用建议
  1. 注意每次pipeline携带数据量(数据量过大最好进行拆分)
  2. pipeline每次只能作用在一个Redis节点上
  3. M操作与pipeline区别

4-4 发布订阅

◆角色

发布者(publisher)
订阅者(subscriber)
频道(channel)

◆模型

在这里插入图片描述
在这里插入图片描述

◆API

publish

publish channel message

使用示例:

redis> publish sohu:tv "hello world"
(integer)3 #订阅者个数

subscribe

subscribe [channel] #一个或多个

unsubscribe
unsubscribe [channel]#一个或多个

其他

psubscribe [pattern..]#订阅模式。
punsubscribe [pattern..]#退订指定的模式。
pubsub channels #列出至少有一个订阅者的频道。
pubsub numsub [channel..]#列出给定频道的订阅者数量
pubsub numpat #列出被订阅模式的数量
◆发布订阅与消息队列

有了消息队列 的不同是订阅者只能有一个接收到消息 就是在抢夺消息
在这里插入图片描述

4-5 bitmap

◆位图

在这里插入图片描述

◆相关命令
setbit key offset value
#给位图指定索引设置值

演示:
在这里插入图片描述

getbit key offset
#获取位图指定索引的值
bitcount key[start end]
# 获取位图指定范围(start到end,单位为字节,如果不指定就是获取全部)位值为1的个数
bitop op destkey key[key …]
# 做多个Bitmap的and(交集)、or(并集)、not(非)、xor(异或) 
# 操作并将结果保存在destkey中  
bitpos key targetBit [start] [end]
#计算位图指定范围(start到end,单位为字节,如果不指定就是获取全部) 第一个偏移量对应的值等于targetBit的位置
◆独立用户统计

在这里插入图片描述
在这里插入图片描述

◆使用经验

1.type=string,最大512MB
2.注意setbit时的偏移量,可能有较大耗时
3.位图不是绝对好。

4-6 hyperloglog

◆新的数据结构?

HyperLogLog
1.基于HyperLogLog算法:极小空间完成独立数量统计。
2.本质还是字符串。

127.0.0.16379>type hyperloglog_key string
◆三个命令
pfadd key element [element..J #向hyperloglog添加元素
pfcount key [key..J #计算hyperloglog的独立总数
pfmerge destkey sourcekey [sourcekey..J #合并多个hyperloglog

使用demo

  1. 添加与获取总数
    在这里插入图片描述
  2. 合并多个hyperloglog
◆内存消耗

在这里插入图片描述

◆使用经验
  1. 是否能容忍错误?(错误率:0.81%,如下面的语句执行结果会每次都不一样)
127.0.0.16379>pfcount 2016_05_01:unique:ids(integer)
1009838
  1. 是否需要单条数据?

4-7 geo

◆GEO是什么

在这里插入图片描述
应用场景举例:可以依据位置信息 来实现例如微信摇一摇的功能 查看附近的酒店 餐馆等

◆5个城市经纬度

在这里插入图片描述

◆相关命令
geo key longitude latitude member
[longitude latitude member..J
#增加地理位置信息

使用案例:
在这里插入图片描述

geopos key member [member..]
#获取地理位置信息

演示:
在这里插入图片描述

geodist key member1 member2 [unit]
#获取两个地理位置的距离
#unit:m(米)、km(干米)、mi(英里)、ft(尺)

在这里插入图片描述

georadius key longitude latitude radiusm|km|ft|mi [withcoord][withdist]
[withhash] [COUNT count] [asc|desc] [store key][storedist key]

georadiusbymember key member  radiusm|km|ft|mi [withcoord]
[withdist] [withhash] [COUNT count] [asc|desc][store key] [storedist key]
#获取指定位置范围内的地理位置信息集合
withcoord:返回结果中包含经纬度。
withdist:返回结果中包含距离中心节点位置。
withhash:返回结果中包含geohash COUNT count:指定返回结果的数量。
ascldesc:返回结果按照距离中心节点的距离做升序或者降序。
store key:将返回结果的地理位置信息保存到指定键。
storedist key:将返回结果距离中心节点的距离保存到指定键

使用示例
在这里插入图片描述

◆相关说明
  1. since3.2+ 版本才会有该功能
  2. type geokey=zset 数据结构其实是zset
  3. 没有删除API:zrem key member 可以使用zset的删除语句

5. Redis持久化的取舍和选择

Redis的持久化功能有效避免因进程退出造成的数据丢失问题,本章将介绍介绍RDB和AOF两种持久化配置和运行流程,以及选择策略

5-1 目录

◆持久化的作用
◆RDB
◆AOF
◆RDB和AOF的抉择

5-2 持久化的作用

◆什么是持久化

redis所有数据保持在内存中,对数据的更新将异步地保存到磁盘上。
在这里插入图片描述

◆持久化的实现方式

快照

  1. MySQL Dump
  2. Redis RDB

写日志

  1. MySQL Binlog
  2. Hbase HLog
  3. Redis AOF

5-3 RDB

◆什么是RDB

在这里插入图片描述

◆触发机制-主要三种方式在这里插入图片描述
save 命令(同步)

在这里插入图片描述
由于是同步命令 会造成阻塞
在这里插入图片描述
执行该命令的文件策略:如存在老的RDB文件,将进行替换
执行该命令的复杂度O(N)

bgsave命令

使用 fork()创建一个子进程来进行RDB的生成 完成后再通知给主进程
在这里插入图片描述
其中使用 fork()速度会更快 但是依然有可能阻塞主线程

执行该命令的文件策略和复杂度与save命令相同

sava与bgsave的不同

在这里插入图片描述

自动生成RDB

在seconds时间内 发生 changes 次改变则触发生成RDB
在这里插入图片描述
实际上改方式无法控制生成RDB的一个频率

配置
save 9001
save 30010
save 6010000
dbfilename dump.rdb #文件名称
dir./ #相关文件存放位置
stop-writes-on-bgsave-error yes # 如果 bgsave发生了错误是否停止写入
rdbcompression yes # rdb文件是否采用压缩格式
rdbchecksum yes #是否对rdb文件进行一个检验

最佳配置(更改相关参数 对于多台机器要对文件名称进行区分 将文件保存在不同的位置)
在这里插入图片描述

◆触发机制-不容忽略方式
  1. 全量复制
  2. debug reload:进行一个debug级别的重启 不需要将内存进行清空 并且在该过程仍会触发RDB文件的生成
  3. shutdown : 进行关闭的时候会进行 RDB文件的生成
◆试验

save阻塞
bgsave fork
真的自动?
RDB长啥样?

待做。。。。

RDB总结
  1. RDB是Redis内存到硬盘的快照,用于持久化。
  2. save通常会阻塞Redis。
  3. bgsave不会阻塞Redis,但是会fork新进程。
  4. save自动配置满足任一就会被执行。
  5. 有些触发机制不容忽视

5-4 AOF

◆RDB现存问题
  1. 耗时、耗性能
    在这里插入图片描述
  2. 不可控、丢失数据
    在这里插入图片描述
◆什么是AOF

创建过程中将执行的命令保存在AOF中
在这里插入图片描述
重启之后再将AOF载入到Redis当中
在这里插入图片描述

◆AOF三种策略
always

在这里插入图片描述
always表示每条命令都执行 fsync 学到硬盘中 防止内容丢失

everysec

在这里插入图片描述
每秒刷新到硬盘中 可能会丢失一秒的数据

no

由操作系统来决定
在这里插入图片描述

三种策略比较

在这里插入图片描述
默认使用第二种

◆AOF重写

过期、重复、没有用或可优化的命令 进行化简 从而减少AOP文件
在这里插入图片描述
AOF重写作用:

  1. 减少硬盘占用量
  2. 加速恢复速度
AOF重写实现两种方式

bgrewriteaof:类似于 Bgsave命令
在这里插入图片描述

AOF重写配置
在这里插入图片描述
需要同时到达如下配置才能够触发

·aof_current_size>auto-aof-rewrite-min-size
·aof_current_size-aof_base_size/aof_base_size>auto-
aof-rewrite-percentage

在这里插入图片描述

◆AOF的配置
appendonly yes # 打开使用aof
appendfilename #"appendonly-${port}.aof" #配置aof的文件名
appendfsync everysec #AOF策略
dir/bigdiskpath 
no-appendfsync-on-rewrite yes 
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
◆实验

待做。。。。

5-5 RDB和AOF抉择

◆RDB和AOF比较

在这里插入图片描述

◆RDB最佳策略
  1. “关"
  2. 集中管理
  3. 主从,从开?
◆AOF最佳策略
  1. “开”:缓存和存储
  2. AOF重写集中管理
  3. everysec
◆最佳策略
  1. 小分片
  2. 缓存或者存储
  3. 监控(硬盘、内存、负载、网络)
  4. 足够的内存
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于点击广告这种场景,我们可以使用Redis作为缓存,来提高访问速度和响应性能。同时,Redis也可以作为数据持久化的解决方案,来保证数据的可靠性。 在Spring Boot项目中使用Redis,可以通过引入相应的依赖,然后配置Redis连接信息来实现。具体步骤如下: 1. 在pom.xml文件中添加Redis相关依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 在application.properties文件中配置Redis连接信息: ```properties # Redis配置 spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password= ``` 3. 在代码中使用RedisTemplate来进行Redis操作,例如: ```java @Autowired private RedisTemplate<String, String> redisTemplate; // 将点击次数存入Redis缓存 redisTemplate.opsForValue().increment("ad-click-count-" + adId); // 从Redis缓存中获取点击次数 Long clickCount = redisTemplate.opsForValue().increment("ad-click-count-" + adId, 0); ``` 4. 配置Redis持久化,可以选择使用Redis自带的RDB和AOF两种方式,例如: ```properties # Redis持久化配置 spring.redis.database=0 spring.redis.redis-cluster=false # 使用RDB持久化 spring.redis.save=900 1 spring.redis.save=300 10 spring.redis.save=60 10000 # 使用AOF持久化 spring.redis.append-on-write=true spring.redis.aof-use-rdb-preamble=true spring.redis.aof-rewrite-incremental-fsync=true ``` 需要注意的是,Redis持久化会对性能产生一定的影响,需要根据具体情况进行选择和调优。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值