千家信息网

自己动手写一个能操作redis的客户端

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,作者:孤独烟 来源:微信订阅号(程序员孤独烟)原文链接: https://mp.weixin.qq.com/s/IBynkex-FHhvJ3tmizvJhA引言redis大家在项目中经常会使用到。官网
千家信息网最后更新 2026年11月01日自己动手写一个能操作redis的客户端

作者:孤独烟 来源:微信订阅号(程序员孤独烟)

原文链接: https://mp.weixin.qq.com/s/IBynkex-FHhvJ3tmizvJhA


引言

redis大家在项目中经常会使用到。官网也提供了多语言的客户端供大家操作redis,如下图所示


但是,大家有思考过,这些语言操作redis背后的原理么?其实,某些大神会说


只要按照redis的协议,发送指定数据给redis,监听返回值即可。


确实,本质原理就是如上面那句话所说。博主也是以这种思路,去看了一下JAVA端的开源组件jedis的源码,然后取其精华,写了一个段能操作redis的demo,希望大家能有所收获。


jedis的github地址为:
https://github.com/xetorthio/jedis


有兴趣的童鞋,也可以自行去阅读。需要说明的是,这毕竟不是源码分析系列文章,不是带你去看jedis的源码。只是借鉴思路,写一个能操作redis的程序。

正文

首先,我先说一下操作思路,如下图所示


说明一下,上面的第四步,就是我们自己要写的操作redis的小demo。

1、先写一个socket监听6379端口

这个程序很easy,度娘一下出来一大把

import java.io.IOException;import java.io.InputStreamReader;import java.io.Reader;import java.net.ServerSocket;import java.net.Socket;public class SocketServer {    public static void main(String[] args) throws IOException {        ServerSocket server = new ServerSocket(6379);        Socket socket = server.accept();        byte[] chars = new byte[64];        socket.getInputStream().read(chars);        System.out.println(new String(chars));    }}

2、采用开源客户端,操作一次redis

我这里用的是JAVA语言的jedis,大家自己也可以用其他的任意语言组件,目的是为了采集客户端在操作redis时,发送出的数据

import redis.clients.jedis.Jedis;public class RedisTest {    public static void main(String[] args) {        Jedis jedis = new Jedis("127.0.0.1", 6379);        jedis.set("eat", "I want to eat");    }}

3、看看socket监听到的数据

在这里运行一下第二步的代码,查看第一步的代码输出的数据,如下所示

*3$3SET$3eat$13I want to eat

那么,这组数据是什么含义呢?
我们去官网进行查询。原来,redis的客户端和服务端采取了一种RESP协议。相应文档地址如下
https://redis.io/topics/protocol
RESP设计巧妙,它的前景在于下面三个方面:

  • Simple to implement.

  • Fast to parse.

  • Human readable.

那么+、-、*、:、$这些符号是什么意思呢?
官网有这么一段话

In RESP, the type of some data depends on the first byte: For Simple Strings the first byte of the reply is "+"
For Errors the first byte of the reply is "-"
For Integers the first byte of the reply is ":"
For Bulk Strings the first byte of the reply is "$"
For Arrays the first byte of the reply is "*"
Additionally RESP is able to represent a Null value using a special variation of Bulk Strings or Array as specified later.
In RESP different parts of the protocol are always terminated with "\r\n" (CRLF).

翻译过来
(1)简单字符串Simple Strings, 以 "+"加号 开头
(2)错误Errors, 以"-"减号 开头
(3)整数型Integer, 以 ":" 冒号开头
(4)大字符串类型Bulk Strings, 以 "$"美元符号开头,长度限制512M
(5)组类型Arrays,以 "*"星号开头
并且,协议的每部分都是以 "\r\n" (CRLF) 结尾的。

OK,那我们刚才的那一串的数据的意思就是(没有看到""\r\n",是因为已经转义了,所以无法看到):

*3   数组包含3个元素,分别是SET、eat、I want to eat$3   是一个字符串,且字符串长度为3SET  字符串的内容$3   是一个字符串,且字符串长度为3eat  字符串的内容$13  是一个字符串,且字符串长度为13I want to eat 字符串的内容

提问,如果是get命令,那么传输的RESP的内容长什么样?
比如有一个命令get eat,那么此时的内容如下所示

*2$3GET$3eat

没有\r\n是因为已经转义了,所以没看到。其他的命令,可以自行测试。

4、尝试构造一样的数据操作redis

OK,经过上面的铺垫。我们如果要对redis做一个set操作,则构造set命令的RESP协议内容,并且利用socket编程,将这串内容发送给redis即可。这里用java的socket编程实现,用其他语言也是一样的。
我们有一个类 RedisClient.java
代码如下

import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.net.UnknownHostException;public class RedisClient {    private Socket socket;                                         private OutputStream outputStream;    private InputStream inputStream;    public RedisClient(String host, int port){        try {            this.socket = new Socket(host,port);            this.outputStream = this.socket.getOutputStream();            this.inputStream = this.socket.getInputStream();        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    public String set(final String key, String value) {        StringBuilder sb = new StringBuilder();        //虽然输出的时候,会被转义,然而我们传送的时候还是要带上\r\n        sb.append("*3").append("\r\n");        sb.append("$3").append("\r\n");        sb.append("SET").append("\r\n");        sb.append("$").append(key.length()).append("\r\n");        sb.append(key).append("\r\n");        sb.append("$").append(value.length()).append("\r\n");        sb.append(value).append("\r\n");        byte[] bytes= new byte[1024];        try {            outputStream.write(sb.toString().getBytes());            inputStream.read(bytes);        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return new String(bytes);    }    public static void main(String[] args) {        RedisClient redisClient = new RedisClient("127.0.0.1", 6379);        String result = redisClient.set("eat", "please eat");        System.out.println(result);         }}

上面的public String set(final String key, String value)方法中,显示了,我们假如需要对redis进行set操作,需要传输的RESP协议的内容。记住,一定要带\r\n字符作为结尾
OK,运行上述代码,你会发现你可以往redis中set数据了,并且控制台输出如下

+OK

提问,你自己会封装get命令么?

总结

本文以一种循序渐进的方式带领大家写了一个能操作redis的demo,希望大家有所收获。

字符 字符串 内容 数据 命令 开头 客户 客户端 代码 语言 长度 就是 思路 源码 程序 转义 面的 输出 孤独 原理 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 手冲咖啡和咖啡机区别 互联网金融科技 哈尔滨大商圈互联网科技有限公司 互联网科技工作委员会副主任毛军 奔汉互联网科技 互联网科技博客 上海卓越科技 互联网 卓越科技互联网 招聘 深圳卡尔迅互联网科技有限公司怎么样 博兴的互联网电子科技公司 济南华为互联网科技产业总部基地 移动互联网科技股 茂名市互联网科技产业园 搜狐科技互联网 速维有品互联网信息科技(苏州)有限公司 开一家科技互联网公司需要多少钱 乌鲁木齐新华智原互联网科技学校 抖集互联网科技技术咨询 珠海东科互联网科技有限公司 互联网科技机房 互联网与科技 山东特亿宝互联网科技有限公司 深圳恒合互联网络科技有限公司 工业互联网科技新基建 万易互联网科技 现代互联网科技股 互联网风格科技公司名称 中国新注册互联网科技 绵阳真晨互联网科技有限公司 互联网科技大佬云集
0