Tencent / Tendis

Tendis is a high-performance distributed storage system fully compatible with the Redis protocol.
http://tendis.cn
Other
2.92k stars 319 forks source link

tendis 读写分离 #200

Open MollyBa opened 2 years ago

MollyBa commented 2 years ago

Description

tendis集群的slave节点能支持读吗?或者可配请求的分布,比如3主3从, 3从(80%的读) + 3主(100%的写+20%的读) 实际业务中对读的要求较高。希望能通过从的水平扩展增大并发,即使数据尚未同步到从也可以接受短暂的延迟。 1当前从只是冷备功能吗?测试发现即使数据在自身,收到的请求也会Redirected到其所在的master 2 集群的从同步进度如何查看呢? 发现info replication的offset和master一致了 但是db还在写。 image


辛苦,感谢大佬答疑

raffertyyu commented 2 years ago

Redis/Tendis都支持从节点的读,可以参考ReadonlyRedis cluster

简单的例子

$ bin/redis-cli -p 51003
127.0.0.1:51003> get a
(error) MOVED 15495 127.0.0.1:51002
127.0.0.1:51003> readonly
OK
127.0.0.1:51003> get a
"b"
127.0.0.1:51003>

第二个问题 db还在写是指?是指还在使用磁盘io吗。大概率可能是compaction后台活动。

MollyBa commented 2 years ago

Redis/Tendis都支持从节点的读,可以参考ReadonlyRedis cluster

简单的例子

$ bin/redis-cli -p 51003
127.0.0.1:51003> get a
(error) MOVED 15495 127.0.0.1:51002
127.0.0.1:51003> readonly
OK
127.0.0.1:51003> get a
"b"
127.0.0.1:51003>

第二个问题 db还在写是指?是指还在使用磁盘io吗。大概率可能是compaction后台活动。

第一个问题,用集群的方式呢? 下图是我自己的测试 `TNA%4P}R03)M71Y5`PZDI0

第二个问题offset已经一致了, 日志还有 还在写,而且 我主从的db文件大小也不一致,是因为不同的压缩算法导致的吗?中途将snappy 更改了lz4 T%WZIV_@I2B5KH15 @0Q%IS

raffertyyu commented 2 years ago

这个是因为你的redis cli加了-c 的选项,在遇到move命令的时候会与新节点建立连接,跳转到新节点上,从node1:51003 跳转到了node2:51002,这个时候就已经变成连接到主节点了。和slave可不可读没什么关系了。然后你再get hello的话,就会从node2:51002 再move 到 node1: 51002。如果你不需要跳转的逻辑,可以去掉-c的选项。这样当你连接51003的时候,属于本机的数据可读,不属于本机的数据,就会返回move,redis cli也不会自动跳转到其他节点了。因为slave也没其他槽位的数据,所以也只能返回move。

第二个问题是,主从上对于存入rocksdb的用户数据是完全一致的,binlog数据受主从不同的binlog回收调度导致数据量不一致,另外就是像rocksdb的compaction等操作在主从节点都不会完全一致,主从节点数据目录大小不一致很正常。 日志还在写是指,如果是说db和dump目录的话,db目录可能会受rocksdb和tendis回收过期数据这些后台操作,发生写入和读操作,如果是dump目录则是周期性导出的binlog二进制文件,会在后台不断执行。这些都可能会在没执行请求的时候运行

MollyBa commented 2 years ago

这个是因为你的redis cli加了-c 的选项,在遇到move命令的时候会与新节点建立连接,跳转到新节点上,从node1:51003 跳转到了node2:51002,这个时候就已经变成连接到主节点了。和slave可不可读没什么关系了。然后你再get hello的话,就会从node2:51002 再move 到 node1: 51002。如果你不需要跳转的逻辑,可以去掉-c的选项。这样当你连接51003的时候,属于本机的数据可读,不属于本机的数据,就会返回move,redis cli也不会自动跳转到其他节点了。因为slave也没其他槽位的数据,所以也只能返回move。

第二个问题是,主从上对于存入rocksdb的用户数据是完全一致的,binlog数据受主从不同的binlog回收调度导致数据量不一致,另外就是像rocksdb的compaction等操作在主从节点都不会完全一致,主从节点数据目录大小不一致很正常。 日志还在写是指,如果是说db和dump目录的话,db目录可能会受rocksdb和tendis回收过期数据这些后台操作,发生写入和读操作,如果是dump目录则是周期性导出的binlog二进制文件,会在后台不断执行。这些都可能会在没执行请求的时候运行

第二个get了 第一个,如果不用-c 那我也无法获取其他节点的数据了,就是,N主N从这种配置, 能不能只在从节点上处理读。及时当前没有这个key的槽信息, 也会redict或者move到其所在的从上。诉求就是, 希望tendis集群中, 读只在从节点上move或者redirect。这在代码里如何体现呢?--- 不知道我有木有表达清楚...

raffertyyu commented 2 years ago

需求理解了,你这个需求就只能修改代码做定制化了。 可以试着修改一下这个函数,用来查询slot归属和move的。

ClusterState::clusterHandleRedirect
MollyBa commented 2 years ago

需求理解了,你这个需求就只能修改代码做定制化了。 可以试着修改一下这个函数,用来查询slot归属和move的。

ClusterState::clusterHandleRedirect

copy that thx

MollyBa commented 2 years ago

需求理解了,你这个需求就只能修改代码做定制化了。 可以试着修改一下这个函数,用来查询slot归属和move的。

ClusterState::clusterHandleRedirect

https://github.com/sewenew/redis-plus-plus 这个能解决这个问题 image