> ## Content Index
> Fetch the complete content index at: https://blog.hacking.pub/llms.txt
> Use this file to discover other available public pages before exploring further.

# nsq 支持分布式事务（三）
- URL: https://blog.hacking.pub/2019/07/04/nsq-zhi-chi-fen-bu-shi-shi-wu-san/
- Published: 2019-07-04T04:00:00.000Z
- Updated: 2020-09-09T03:51:56.000Z
- Author: chainhelen
- Tags: go, go语言, golang, go-nsq, 分布式, 事务, nsq, nsqio

[主备同步 代码提交记录](https://github.com/chainhelen/dtnsq/commit/1f460aba2a54a2ac399daa1d51ae13a0f9878c06?ref=blog.hacking.pub)

##### 完成度

只完成了主从复制；但是主备切换、依据处理能力动态调整消费能力、一些`write`失败逻辑处理 没有完成

##### 基本逻辑

###### 数据

主要分成了三部分数据的复制

1. 发送`SLAVE_SYNC_INFO`命令，返回所有的`topic`和其对应的`channel`
2. 发送`SLAVE topic_name`命令，携带当前`topic`的关键4个参数`fileindex` `filenum` `totalMsgCnt` `viroffset`和一个`maxnum`希望本次同步返回的消息数量，返回 `master`的关键参数和消息本身
3. 发送`SLAVE topic_name channel_name`，携带当前的4个关键参数，返回`master`的关键参数

###### 客户端请求

对于`slave`是不可以接受普通`client`的请求的 ，连接`master`复用了`master`与`client`的 `tcp`端口

###### 同步 or 异步

一开始写了一个`同步`版本，就是`slave`每次发送`SLAVE`消息，就等待结果

后来改成了`异步`发送，`异步`里面主要需要做大量的`check`避免时序问题，造成`SYNC`数据错乱问题

###### conn

`conn`需要上锁和保持心跳， 最好加上`SetDeadline`来确保心跳包没有抵达情况下`tcp假死`

###### 异常

异常问题，例如如果`slave`和 `master`设置的单个最大文件大小不一致，应该如何落盘

异步接受报文，如果接收到同一个`topic`或者`chanel`，应该需要一个乐观锁来保证数据最新

使用`sync.pool`来控制`bytes.Buffer`的内存块使用前需要`bps.Reset()`