Redis(3)- Redis协议相关

本文详细介绍了Redis的相关特性,包括响应式协议RESP、模拟Redis服务端的Java代码、Lua在Redis中的应用、Pipeline的原理与优势以及事务的使用方法。通过实例展示了如何进行性能测试、设置与获取键值、批量操作以及事务处理。同时,文章提及了Redis的消息发布与订阅功能,适合对Redis感兴趣的读者深入理解其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

主要包括Redis协议,Redis集群搭建,Redis哨兵机制

一、Redis协议

RESP

mget str:1
*2 #多少组
$4	#这组的字符长度
mget
$5
str:1
  • Redis测试
redis-cli判断访问的redis服务是否通 ping 命令
[root@localhost redis]# ./redis-cli -h 192.168.42.119 -a 12345678 -p 6379 ping
PONG

[root@localhost redis]# ./redis-cli -h 192.168.42.119 -a 12345678 -p 6379 -r 100 -i 1 info |grep used_memory_human
#每秒输出内存使用量,输100次
used_memory_human:1.32M
used_memory_human:1.32M
used_memory_human:1.32M
used_memory_human:1.32M

[root@localhost redis]# ./redis-server --test-memory 1024
Addressing test [1]AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`有点卡顿`^C.................................................................................[root@localhost redis]# 
#检测操作系统能否提供1G内存给redis, 常用于测试,想快速占满机器内存做极端条件的测试,可使用这个指令

./redis-benchmark -c 100 -n 10000
测试命令事例:
`1、./redis-benchmark -h 192.168.42.119 -p 6379 -c 100 -n 100000 `
100个并发连接,100000个请求,检测host为localhost 端口为6379的redis服务器性能 
`2、./redis-benchmark -h 192.168.42.119 -p 6379 -q -d 100  `
测试存取大小为100字节的数据包的性能

`3、./redis-benchmark -t set,lpush -n 100000 -q`
只测试 set,lpush操作的性能

`4、./redis-benchmark -n 100000 -q script load `"redis.call('set','foo','bar')"
只测试某些数值存取的性能

`[root@localhost redis]# ./redis-benchmark -h 192.168.42.119 -p 6379 -q -d 100` 
PING_INLINE: 29664.79 requests per second
PING_BULK: 31065.55 requests per second
SET: 30284.68 requests per second
GET: 31055.90 requests per second
INCR: 31007.75 requests per second
LPUSH: 29788.50 requests per second
RPUSH: 31084.86 requests per second
LPOP: 30193.24 requests per second
RPOP: 30193.24 requests per second
SADD: 30413.62 requests per second
HSET: 31466.33 requests per second
SPOP: 30358.23 requests per second
LPUSH (needed to benchmark LRANGE): 30845.16 requests per second
LRANGE_100 (first 100 elements): 30674.85 requests per second
LRANGE_300 (first 300 elements): 29806.26 requests per second
LRANGE_500 (first 450 elements): 30021.01 requests per second
LRANGE_600 (first 600 elements): 30349.01 requests per second
MSET (10 keys): 25813.11 requests per second

二.Redis伪服务端

Lua是一个小巧的脚本语言, Lua由标准C编写而成,代码简洁优美,几乎在所有操作系统和平台上都可以编译,运行。一个完整的Lua解释器不过200k,在所有脚本引擎中,Lua的速度是最快的。

1 Redis伪服务端

/**模拟redis客户端协议*/
public class RedisClient {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("127.0.0.1", 6379);
        jedis.set("user:name","cp");
        jedis.close();
    }
}

/**Redis伪服务端 接收客户端数据*/
public class RedisServerSocket {

    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(6379)) {
            Socket accept = serverSocket.accept();
            byte[] result = new byte[1024];
            accept.getInputStream().read(result);
            System.out.println(new String(result));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

*3
$3
SET
$9
user:name
$2
cp

2 LUA在Redis上的应用-使用脚本文件

Redis可以加载Lua脚本文件,返回SHA值,然后Redis根据SHA值调用 evalsha

三、Pipeline

RTT:Round trip time 往返时间
  • 为什么要使用Pipeline?

      正常请求,每操作一次set get 都要执行以下步骤
      建立连接- 发送指令 -等待执行 - 返回结果
      大批量使用这种方式耗费网络资源,效率低  for 5000  就是5000次
      使用pipeline    
      建立连接 - 发送5000指令 - 单线程执行 -返回结果,减少了连接建立断开的时间消耗
    
  • 与原生批命令区别?

      1、原生批命令是原子性,pipeline是非原子性
      2、原生批命令批命令一命令多个key,pipeline支持多命令(存在事务)
      3、原生批命令只需服务端完成,pipeline是客户端与服务端一起完成
    
  • Pipeline的正确使用方式

      1、Pipeline数据量不能太大
      2、执行批量命令时间太长,客户端会阻塞
      3、Pipeline大量数据可以拆分成多个小Pipeline执行
    
public static void main(String[] args) {
        JedisPool pool = new JedisPool(new JedisPoolConfig(), JedisConstants.ip, JedisConstants.port, 100000, JedisConstants.auth);
        Jedis jedis = pool.getResource();
        //使用Pipeline 批量执行
        Pipeline pipelined = jedis.pipelined();
        wrapPipelineDel(pipelined);
        //wrapPipelineAdd(pipelined);
        System.out.println(JSONObject.toJSONString(pipelined));
        //执行-无结果返回
        //pipelined.sync();
        //执行并获取返回结果
        List<Object> objects = pipelined.syncAndReturnAll();
        System.out.println(JSONObject.toJSONString(objects));
    }

    public static void wrapPipelineDel(Pipeline pipelined) {
        for (int i = 0; i < 1000; i++) {
            pipelined.del("str:" + i);
        }
    }

    public static void wrapPipelineAdd(Pipeline pipelined) {
        for (int i = 0; i < 1000; i++) {
            pipelined.set("str:" + i, i + "");
        }
    }

四、事务

Redis是弱事务,能进行简单回滚
multi #开启事务
discard #取消事务
exec #提交事务

# 事务异常
192.168.42.120:6379> multi
OK
192.168.42.120:6379> sadd user:name zcp
QUEUED
192.168.42.120:6379> sadd user:age 20
QUEUED
192.168.42.120:6379> get user:name
QUEUED
192.168.42.120:6379> exec
1) (integer) 1
2) (integer) 1
3) (error) WRONGTYPE Operation against a key holding the wrong kind of value

# discard 取消事务
192.168.42.120:6379> multi
OK
192.168.42.120:6379> set tt 1
QUEUED
192.168.42.120:6379> 
192.168.42.120:6379> discard
OK
192.168.42.120:6379> 
192.168.42.120:6379> get tt
(nil)

# Redis WrongType 会进行回滚,其它不会回滚 
#简单回滚 
192.168.42.120:6379> multi
OK
192.168.42.120:6379> set aa 1
QUEUED
192.168.42.120:6379> sett ad 1
(error) ERR unknown command 'sett'
192.168.42.120:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
192.168.42.120:6379> 
192.168.42.120:6379> 
192.168.42.120:6379> get aa
(nil)

#进行回滚
192.168.42.120:6379> multi
OK
192.168.42.120:6379> add aa 1
(error) ERR unknown command 'add'
192.168.42.120:6379> 
192.168.42.120:6379> 
192.168.42.120:6379> 
192.168.42.120:6379> 
192.168.42.120:6379> 
192.168.42.120:6379> set tt 1
QUEUED
192.168.42.120:6379> sadd tt 1
QUEUED
192.168.42.120:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.

五、消息发布与订阅

redis主要提供发布消息、订阅频道、取消订阅以及按照模式订阅和取消订阅,
和很多专业的消息队列(kafka rabbitmq),redis的发布订阅显得很lower, 比如
无法实现消息规程和回溯, 但就是简单,如果能满足应用场景,用这个也可以

1,发布消息:
   publish channel:test "hello world"

2,订阅消息
   subscrible channel:test

3,查看订阅数
   pubsub numsub channel:test

4,取消订阅
   unsubscribe channel:test

5,按模式订阅和取消订阅
   psubscribe ch* 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值