Zookeeper 性能影响最相关的两个方面,网络速度和磁盘写性能。
影响 zookeeper 事务刷盘的相关参数:
参数 |
默认值 |
说明 |
flushDelay |
0 |
两次刷盘之间相隔多久 |
maxBatchSize |
1000 |
两次刷盘直接允许堆积多少个写请求 |
forceSync |
true |
刷盘操作本身是否需要立即刷盘,默认 true 意味着刷盘操作必须同步到硬件,不丢失数据 |
影响刷盘操作的三个参数,前两个控制业务逻辑,后一个控制具体的刷盘行为。
每一次事务操作落盘前用来检查是否需要落盘的方法 shouldFlush:
1private boolean shouldFlush() { 2 long flushDelay = zks.getFlushDelay(); 3 long maxBatchSize = zks.getMaxBatchSize(); 4 if ((flushDelay > 0) && (getRemainingDelay() == 0)) { 5 return true; 6 } 7 return (maxBatchSize > 0) && (toFlush.size() >= maxBatchSize); 8}
shouldFlush 方法用来确定是否需要刷盘操作,可以看到在默认的情况下,只要堆积了 maxBatchSize 个写入请求后才会刷盘,因为 flushDelay 是 0,不生效,这样要等到堆积 1000 个写请求会导致数据不安全。
1Request si = queuedRequests.poll(pollTime, TimeUnit.MILLISECONDS); 2if (si == null) { 3 /* We timed out looking for more writes to batch, go ahead and flush immediately */ 4 flush(); 5 si = queuedRequests.take(); 6}
通过以上代码可知,在 SyncRequestProcessor 的 run 方法每读取到一个 request 时,会立刻做一个判断,如果当前的请求队列已经空了(读取到的 request(si) 是 null),在循环任务阻塞前会立即调用 flush 方法,所以即使只有一个写请求,也会被立即 flush,并不会有响应延迟的问题。只有在请求量非常大并且前置环节速度快的情况下写请求才会在两次刷盘之间堆积。
Read more...