切主期间读写不可用多久?优雅切主和崩溃切主差多少?调小 electionTimeoutMillis 有用吗?写入会不会丢?这篇用一个持续写入的客户端在 3 节点副本集上量三种切主方式的不可写时间。
方式 A:primary 上执行 replSetStepDown(优雅切主,等 secondary 追平)
retryWrites=True :动作之后的最大间隔 0.03 s(平时的中位数间隔 11 ms);客户端看到的错误 0 个 {};确认写入 2271 条,丢失 0 条
retryWrites=False:动作之后的最大间隔 0.03 s;客户端看到的错误 0 个 {};确认写入 2201 条,丢失 0 条
方式 B:kill -9 primary(崩溃,默认 electionTimeoutMillis = 10 s)
retryWrites=True :动作之后的最大间隔 10.83 s(平时 12 ms);错误 0 个 {};确认写入 1466 条,丢失 0 条
方式 C:同样 kill -9,但把 electionTimeoutMillis 调成 4000(必须大于心跳间隔 2000)
retryWrites=True :动作之后的最大间隔 4.19 s(平时 12 ms);错误 0 个 {};确认写入 1122 条,丢失 0 条优雅切主(replSetStepDown)让 primary 等 secondary 追平后让位,不可写时间只有约 30 ms;kill -9 后 secondary 要等 electionTimeoutMillis(默认 10 秒)才发起选举,不可写时间约 10.8 秒;调到 4 秒则约 4.2 秒。retryWrites 的驱动等到新 primary 出现后重试,客户端没有看到错误,三种方式下 w:majority 确认的写入都没有丢失。
方式 不可写时间 replSetStepDown(优雅) 0.03 s kill -9,electionTimeoutMillis 10 s 10.83 s kill -9,electionTimeoutMillis 4 s 4.19 s
0.03 s、4.19 s、10.83 s。electionTimeoutMillis 越小崩溃切主越快,但必须大于心跳间隔(默认 2 秒),调得太小会增加误判。
primary 被 kill 后的 14 秒里,两个线程每 0.2 秒各读一次:
secondary 读偏好:69 次读,失败 0 次;单次读的最大耗时 5 ms;耗时超过 1 s 的读有 0 次(最长的一次在 kill 后 0.0 s 开始)
primary 读偏好: 18 次读,失败 0 次;单次读的最大耗时 10465 ms;耗时超过 1 s 的读有 1 次(最长的一次在 kill 后 0.0 s 开始)secondary 读偏好的读不受影响;primary 读偏好的读会阻塞到新 primary 出现(这里一次读阻塞了 10.5 秒)。