特性
- 支持RESP2和RESP3协议
- 接口设计兼容jedis接口语义
- 丰富的管理命令支持
- 支持单连接多线程模式
- 支持发布订阅模式
- 支持哨兵模式和集群模式
- 完备的单元测试覆盖
- 架构简洁,易于扩展
开发计划
- 2024.3.22 完成支持单机模式的RESP2和RESP3协议的客户端,提供Beta版本
- 2024.4.16 完成支持Sentinel集群模式的客户端,提供Beta版本
- 2024.5.31 完成支持Redis集群模式的客户端,提供Beta版本
- 2024.6.30 完成1.0.0 RC版本的发布
支持版本
Redis 7.x: 目前在Redis 7.0.0——Redis 7.2.4版本上完成兼容性测试
Redis 6.x: 目前在Redis 6.0.0——Redis 6.2.14版本上完成兼容性测试
其他版本的兼容性测试陆续完善中,敬请期待
工程目录结构
工程目录结构
|---samples Redis客户端使用示例目录
|---src Redis客户端源码目录
|---test Redis客户端单元测试目录
| |---UT 通用命令的单元测试目录
|---HLT 需要准备特殊环境的命令的单元测试
|---module.json
|---README.md
已经实现的命令
BitMap数据类型操作命令
BITCOUNT, BITFIELD, BITFIELD_RO, BITOP, GETBIT, SETBIT, BITPOS
地理空间坐标
GEOADD, GEODIST, GEOHASH, GEOENCODE, GEODECODE, GEOPOS, GEORADIUS, GEORADIUS_RO, GEORADIUSBYMEMBER, GEORADIUSBYMEMBER_RO, GEOSEARCH, GEOSEARCHSTORE
Key命令
COPY, DEL, DUMP, EXISTS, EXPIRE, EXPIREAT, EXPIRETIME, MOVE, KEYS, MIGRATE, MEMORYUSAGE, OBJECTENCODING, OBJECTFREQ, OBJECTIDLETIME, OBJECTREFCOUNT, PERSIST, PEXPIRE, PEXPIREAT, PEXPIRETIME, PTTL, RANDOMKEY, RENAME,RENAMENX, RESTORE, SCAN, SORT, SORT_RO, TOUCH, TTL, TYPE, UNLINK
Hash数据类型操作命令
HDEL, HEXISTS, HGET, HGETALL, HINCRBY, HINCRBYFLOAT, HKEYS, HLEN, HMGET, HMSET, HRANDFIELD, HSCAN, HSET, HSETNX, HSTRLEN, HVALS
List数据类型操作命令
BLMOVE, BLMPOP, BLPOP, BRPOP, BRPOPLPUSH, LINDEX, LINSERT, LLEN, LMOVE, LMPOP, LPOP, LPOS, LPUSH, LPUSHX, LRANGE, LREM, LSET, LTRIM, RPOP, RPOPLPUSH, RPUSH, RPUSHX
Set数据类型操作命令
SADD, SCARD, SDIFF, SDIFFSTORE, SINTER, SINTERCARD, SINTERSTORE, SISMEMBER, SMEMBERS, SMOVE, SPOP, SRANDMEMBER, SREM, SSCAN, SUNION, SUNIONSTORE
Stream数据类型操作命令
XACK, XADD, XAUTOCLAIM, XCLAIM, XDEL, XGROUP CREATE, XGROUP CREATECONSUMER, XGROUP DELCONSUMER, XGROUP DESTROY, XGROUP SETID, XINFO CONSUMERS, XINFO GROUPS, XINFO STREAM, XLEN, XPENDING, XRANGE, XREVRANGE, XREAD, XREADGROUP, XTRIM
String数据类型操作命令
APPEND, DECR, DECRBY, GET, GETDEL, GETEX, GETRANGE, GETSET, INCR, INCRBY, INCRBYFLOAT, MGET, MSET, MSETNX, PSETEX, SET, SETEX, SETNX, SETRANGE, STRLEN, SUBSTR
ZSet数据类型操作命令
BZMPOP, BZPOPMAX, ZADD, ZCARD, ZCOUNT, ZDIFF, ZDIFFSTORE, ZINCRBY, ZINTER, ZINTERCARD, ZINTERSTORE, ZLEXCOUNT, ZMSCORE, ZMPOP, ZPOPMIN, ZPOPMAX, ZRANDMEMBER, ZRANGE, ZRANGEBYSCORE, ZRANGESTORE, ZRANK, ZREM, ZREMRANGEBYRANK, ZREMRANGEBYSCORE, ZREVRANGE, ZREVRANGEBYLEX, ZREVRANGEBYSCORE, ZREVRANK, ZSCAN, ZSCORE, ZUNION, ZUNIONSTORE, ZREMRANGEBYLEX, ZRANGEBYLEX
HyperLogLog命令
PFADD, PFCOUNT, PFMERGE
Script和Function命令
EVAL, EVAL_RO, EVALSHA, EVALSHA_RO, SCRIPT EXISTS, SCRIPT FLUSH, SCRIPT KILL, SCRIPT LOAD
FCALL, FCALL_RO, FUNCTION DELETE, FUNCTION DUMP, FUNCTION FLUSH, FUNCTION KILL, FUNCTION LIST, FUNCTION LOAD, FUNCTION RESTORE, FUNCTION STATS
Connection Mangement命令
AUTH, ECHO, PING, RESET
DataBase 命令
DBSIZE, FLUSHDB, FLUSHALL, SELECT, SWAPDB
ACL命令
ACL CAT, ACL DELUSER, ACL DRYRUN, ACL GENPASS, ACL GETUSER, ACL LIST, ACL LOAD, ACL LOG, ACL SAVE, ACL SETUSER, ACL USERS, ACL WHOAMI
CLIENT命令
CLIENT GETNAME, CLIENT ID, CLIENT INFO, CLIENT KILL, CLIENT LIST, CLIENT NO-EVICT, CLIENT NO-TOUCH, CLIENT PAUSE, CLIENT SETINFO, CLIENT SETNAME, CLIENT UNBLOCK, CLIENT UNPAUSE
CONFIG命令
CONFIG GET, CONFIG RESETSTAT, CONFIG REWRITE, CONFIG SET
Server Mangement命令
BGREWRITEAOF, BGSAVE, INFO, LASTSAVE, LATENCYDOCTOR, LOLWUT, REPLICAOF, SAVE, SHUTDOWN, SLAVEOF
其他
MEMORY DOCTOR, MEMORY PURGE, MEMORY STATS, ROLE, WAIT, WAITAOF
1. 在工程中使用Redis仓颉语言客户端
1.1 通过源码方式引入Redis客户端依赖
仓颉0.53.4以上版本:在项目的cjpm.toml中添加dependencies引入redis_sdk依赖:
[dependencies]
redis_sdk = {git = "https://gitcode.com/Cangjie-TPC/redis-sdk.git", branch = "master", version = "2.0.0"}
仓颉0.45.2和0.51.4版本,请参考 Branch_cj0.51.4 分支中的说明。
更新依赖,运行cjpm update会自动下载依赖redis_sdk项目到~/.cjpm目录下
$> cjpm update
1.2 编译Redis仓颉语言客户端并导入静态库依赖
编译Redis仓颉语言客户端请参考: 用户手册
引入编译好的静态库依赖和通过源码方式引入依赖,任意选取一种方式即可。 参考"1.1 通过源码方式引入Redis客户端依赖"。
仓颉0.53.4以上版本,需要先确定平台对应的target-name:
例如Windows X64平台执行cjc -v
命令返回如下:
$cjc -v
Cangjie Compiler: 0.53.4 (cjnative)
Target: x86_64-w64-mingw32
例如Linux X64平台执行cjc -v
命令返回如下:
$cjc -v
Cangjie Compiler: 0.53.4 (cjnative)
Target: x86_64-unknown-linux-gnu
仓颉0.53.4版本,在工程的cjpm.toml中添加平台对应的二进制依赖,以Linux X64为例:
[target.x86_64-unknown-linux-gnu.bin-dependencies.package-option]
"hyperion.buffer" = "${path_to_redis_sdk}/build/release/hyperion/hyperion.buffer.cjo"
"hyperion.logadapter" = "${path_to_redis_sdk}/build/release/hyperion/hyperion.logadapter.cjo"
"hyperion.objectpool" = "${path_to_redis_sdk}/build/release/hyperion/hyperion.objectpool.cjo"
"hyperion.threadpool" = "${path_to_redis_sdk}/build/release/hyperion/hyperion.threadpool.cjo"
"hyperion.transport" = "${path_to_redis_sdk}/build/release/hyperion/hyperion.transport.cjo"
"redis_sdk.client.api" = "${path_to_redis_sdk}/build/release/redis_sdk/redis_sdk.client.api.cjo"
"redis_sdk.client.commands" = "${path_to_redis_sdk}/build/release/redis_sdk/redis_sdk.client.commands.cjo"
"redis_sdk.client.commands.impl" = "${path_to_redis_sdk}/build/release/redis_sdk/redis_sdk.client.commands.impl.cjo"
"redis_sdk.client" = "${path_to_redis_sdk}/build/release/redis_sdk/redis_sdk.client.cjo"
仓颉0.45.2和0.51.4版本,请参考 Branch_cj0.51.4 分支中的说明。
1.3 创建RedisClient用于执行Redis命令
import redis_sdk.client.api.*
import redis_sdk.client.commands.*
import redis_sdk.client.*
public func getRedisClient(): RedisClient {
let redisClient = RedisClientBuilder.builder()
.host("127.0.0.1")
.port(6379)
.readTimeout(Duration.second * 60)
.writeTimeout(Duration.second * 30)
.receiveBufferSize(32768)
.sendBufferSize(32768)
.build()
return redisClient
}
1.4 使用RedisClient执行Redis命令操作
import redis_sdk.client.api.*
import redis_sdk.client.commands.*
import redis_sdk.client.*
main() {
// 获取Redis客户端
let client = getRedisClient()
// 执行 SET testKey1 testValue1 XX命令
let result = client.set("testKey1", "testValue1", SetParams().xx())
if (let Some(result) <- result) {
println(result)
} else {
println("nil")
}
// 执行 GET testKey1命令
var getResult = client.get("testKey1")
if (let Some(getResult) <- getResult) {
println(getResult)
} else {
println("nil")
}
}
2. 扩展Redis仓颉语言客户端
2.1 Redis命令处理模块的架构
Redis命令处理的架构图如下:
RedisCommand类
Redis命令的实现类
包含以下成员:
commandType: Redis命令的名称
commandArgs: Redis命令的参数列表
response: Redis命令的响应消息,类型为RedisMessage
exception: 执行Redis命令发生的异常
CommandArg类
封装Redis命令的基本类型参数,包括Array、String、Integer、Double
CommandArgs类
Redis命令的参数列表,包含CommandArg的列表
CompositeArgs类
封装Redis命令参数列表中存在关联关系的多个参数
调用buildArgs(CommandArgs)方法将多个存在关联的参数添加到CommandArgs的参数列表中
RedisMessage类
封装Redis命令的响应消息
RESP2协议对应的RedisMessage:
SIMPLE_STRINGS: StringRedisMessage
SIMPLE_ERRORS: ErrorRedisMessage
INTEGERS: IntegerRedisMessage
BULK_STRINGS: BulkStringRedisMessage
ARRAYS: ArraysRedisMessage
RESP3协议对应的RedisMessage:
NULLS:NullArraysRedisMessage
BOOLEANS:BooleanRedisMessage
DOUBLES:DoubleRedisMessage
BIG_NUMBERS:BigNumberRedisMessage
BULK_ERRORS:BulkErrorRedisMessage
VERBATIM_STRINGS:VerbatimRedisMessage
MAPS:MapRedisMessage
SETS:SetRedisMessage
PUSHES:PushesRedisMessage
ResponseBuilder类
将RedisMessage转换为命令执行的结果
基本数据类型的RepsonseBuilder实现:
StringResponseBuilder
IntegerResponseBuilder
DoubleResponseBuilder
BoolResponseBuilder
NillableStringResponseBuilder
集合类型的RepsonseBuilder实现:
ListResponseBuilder
SetOfResponseBuilder
PrimitiveMapResponseBuilder<String, T>
ListOfAnyResponseBuilder
MapOfAnyResponseBuilder
ParameterizedRedisCommand类
RedisCommand的子类,支持将Redis命令的响应构建为类型T,包含成员RepsonseBuilder用于处理响应
注意: 需要返回响应的命令,可以使用RedisCommand类, 也可以使用ParameterizedRedisCommand类;
不需要返回响应的命令,只能使用RedisCommand类
2.2 Redis编解码模块的架构
Redis编解码处理的架构图如下:
MessageCompletedHandler接口
解码二进制报文时,判断二进制报文是否包含完整的消息报文
ByteToRedisMessageDecoder类
RESP协议解码器实现,将RESP协议的二进制报文转换为RedisMessage
该类实现了MessageCompletedHandler接口
RedisCommandToByteEncoder类
RESP协议编码器实现,将RedisCommand编码为RESP协议的二进制报文
RedisCodec类
实现了Hyperion TCP框架的IOFilter接口,处理Redis命令和Redis响应的编解码
RedisCommandHandler类
实现了Hyperion TCP框架的IOFilter接口,处理RedisMessage和RedisCommand的关联
RedisSubscriberHandler类
实现了Hyperion TCP框架的IOFilter接口,处理RedisMessage和Redis订阅者的关联
在未切换成订阅模式之前,处理方式和RedisCommandHandler类一致(处理认证和握手相关命令)
切换成订阅模式之后,只能执行以下命令:
SUBSCRIBE channel [channel …]
PSUBSCRIBE pattern [pattern …]
UNSUBSCRIBE channel [channel …]
PUNSUBSCRIBE pattern [pattern …]
UNSUBSCRIBE
PUNSUBSCRIBE
PING
PING message
RedisClientConfig
记录Redis客户端的参数配置
RedisClientBuilder类
用于创建RedisClient对象,RedisClient可以执行Redis命令
RedisClient类
执行Redis命令,并返回命令执行的结果
RedisSubscriberBuilder类
用于创建RedisSubscriber对象,RedisSubscriber可以订阅消息
RedisSubscriber类
订阅Redis频道的消息
2.3 编写Redis命令的实现
对于一个特定的数据类型,例如String类型,需要提供以下2个接口:
StringCommands接口:定义String类型的操作命令对应的接口
StringCommansBuidldler接口:构建Sting类型相关命令对应的ParameterizedRedisCommand对象
需要实现以上2个接口:
StringCommandsImpl类:提供String类型的操作命令对应的实现
StringCommansBuidlerImpl类:构建Sting类型相关命令对应的ParameterizedRedisCommand对象
RedisClient类需要实现StringCommands接口,并将String类型的相关方法委托给StringCommandsImpl类
String类型,支持超时参数的SET命令按如下方式构建(参考StringCommansBuidlerImpl类):
public func set(key: String, value: String, params: SetParams): ParameterizedRedisCommand<?String> {
let commandArgs = CommandArgs().add(StringArg(key)).add(StringArg(value))
let command = ParameterizedRedisCommand<?String>(
CommandType.SET,
commandArgs,
params,
ResponseBuilderFactory.nillableStringBuilder
)
return command
}
String类型,支持超时参数的SET命令的实现如下:
public func set(key: String, value: String, params: SetParams): ?String {
let redisCommand = RedisCommandBuilder.set(key, value, params)
return executeCommand<String>(redisCommand)
}
调用String类型,支持超时参数的SET命令:
let client = RedisClientBuilder.builder()
.host(servHost)
.port(servPort)
.password(servPass)
.build()
// 500秒后超时
let result = client.set(myKey, myValue,
SetParams().exAt(DateTime.now().addSeconds(500).toUnixTimeStamp().toSeconds())
为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)全栈开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页)+《OpenHarmony 嵌入式开发学习手册》,希望对大家有所帮助:https://qr21.cn/FV7h05
《鸿蒙开发学习手册》:
如何快速入门:https://qr21.cn/FV7h05
- 基本概念
- 构建第一个ArkTS应用
- ……
开发基础知识:https://qr21.cn/FV7h05
- 应用基础知识
- 配置文件
- 应用数据管理
- 应用安全管理
- 应用隐私保护
- 三方应用调用管控机制
- 资源分类与访问
- 学习ArkTS语言
- ……
基于ArkTS 开发:https://qr21.cn/FV7h05
- Ability开发
- UI开发
- 公共事件与通知
- 窗口管理
- 媒体
- 安全
- 网络与链接
- 电话服务
- 数据管理
- 后台任务(Background Task)管理
- 设备管理
- 设备使用信息统计
- DFX
- 国际化开发
- 折叠屏系列
- ……
鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH
鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH
1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向