Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b251e2f

Browse files
authored
Update listener (vesoft-inc#4925)
* remove Listener::apply * remove Listener::apply * Revert "remove Listener::apply" This reverts commit 7898a20.
1 parent 2c447a9 commit b251e2f

File tree

5 files changed

+241
-148
lines changed

5 files changed

+241
-148
lines changed

src/kvstore/Listener.cpp

Lines changed: 0 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
#include "kvstore/LogEncoder.h"
1111

1212
DEFINE_int32(listener_commit_interval_secs, 1, "Listener commit interval");
13-
DEFINE_int32(listener_commit_batch_size, 1000, "Max batch size when listener commit");
1413
DEFINE_uint32(ft_request_retry_times, 3, "Retry times if fulltext request failed");
1514
DEFINE_int32(ft_bulk_batch_size, 100, "Max batch size when bulk insert");
1615
DEFINE_int32(listener_pursue_leader_threshold, 1000, "Catch up with the leader's threshold");
@@ -161,123 +160,7 @@ void Listener::doApply() {
161160
});
162161
}
163162

164-
void Listener::processLogs() {
165-
std::unique_ptr<LogIterator> iter;
166-
{
167-
std::lock_guard<std::mutex> guard(raftLock_);
168-
if (lastApplyLogId_ >= committedLogId_) {
169-
return;
170-
}
171-
iter = wal_->iterator(lastApplyLogId_ + 1, committedLogId_);
172-
}
173-
174-
LogID lastApplyId = -1;
175-
// the kv pair which can sync to remote safely
176-
std::vector<KV> data;
177-
while (iter->valid()) {
178-
lastApplyId = iter->logId();
179-
180-
auto log = iter->logMsg();
181-
if (log.empty()) {
182-
// skip the heartbeat
183-
++(*iter);
184-
continue;
185-
}
186-
187-
DCHECK_GE(log.size(), sizeof(int64_t) + 1 + sizeof(uint32_t));
188-
switch (log[sizeof(int64_t)]) {
189-
case OP_PUT: {
190-
auto pieces = decodeMultiValues(log);
191-
DCHECK_EQ(2, pieces.size());
192-
data.emplace_back(pieces[0], pieces[1]);
193-
break;
194-
}
195-
case OP_MULTI_PUT: {
196-
auto kvs = decodeMultiValues(log);
197-
DCHECK_EQ(0, kvs.size() % 2);
198-
for (size_t i = 0; i < kvs.size(); i += 2) {
199-
data.emplace_back(kvs[i], kvs[i + 1]);
200-
}
201-
break;
202-
}
203-
case OP_REMOVE:
204-
case OP_REMOVE_RANGE:
205-
case OP_MULTI_REMOVE: {
206-
break;
207-
}
208-
case OP_BATCH_WRITE: {
209-
auto batch = decodeBatchValue(log);
210-
for (auto& op : batch) {
211-
// OP_BATCH_REMOVE and OP_BATCH_REMOVE_RANGE is igored
212-
if (op.first == BatchLogType::OP_BATCH_PUT) {
213-
data.emplace_back(op.second.first, op.second.second);
214-
}
215-
}
216-
break;
217-
}
218-
case OP_TRANS_LEADER:
219-
case OP_ADD_LEARNER:
220-
case OP_ADD_PEER:
221-
case OP_REMOVE_PEER: {
222-
break;
223-
}
224-
default: {
225-
VLOG(2) << idStr_ << "Unknown operation: " << static_cast<int32_t>(log[0]);
226-
}
227-
}
228163

229-
if (static_cast<int32_t>(data.size()) > FLAGS_listener_commit_batch_size) {
230-
break;
231-
}
232-
++(*iter);
233-
}
234-
235-
// apply to state machine
236-
if (lastApplyId != -1 && apply(data)) {
237-
std::lock_guard<std::mutex> guard(raftLock_);
238-
lastApplyLogId_ = lastApplyId;
239-
persist(committedLogId_, term_, lastApplyLogId_);
240-
VLOG(2) << idStr_ << "Listener succeeded apply log to " << lastApplyLogId_;
241-
lastApplyTime_ = time::WallClock::fastNowInMilliSec();
242-
}
243-
}
244-
245-
std::tuple<nebula::cpp2::ErrorCode, int64_t, int64_t> Listener::commitSnapshot(
246-
const std::vector<std::string>& rows,
247-
LogID committedLogId,
248-
TermID committedLogTerm,
249-
bool finished) {
250-
VLOG(2) << idStr_ << "Listener is committing snapshot.";
251-
int64_t count = 0;
252-
int64_t size = 0;
253-
std::vector<KV> data;
254-
data.reserve(rows.size());
255-
for (const auto& row : rows) {
256-
count++;
257-
size += row.size();
258-
auto kv = decodeKV(row);
259-
data.emplace_back(kv.first, kv.second);
260-
}
261-
if (!apply(data)) {
262-
LOG(INFO) << idStr_ << "Failed to apply data while committing snapshot.";
263-
return {
264-
nebula::cpp2::ErrorCode::E_RAFT_PERSIST_SNAPSHOT_FAILED, kNoSnapshotCount, kNoSnapshotSize};
265-
}
266-
if (finished) {
267-
CHECK(!raftLock_.try_lock());
268-
leaderCommitId_ = committedLogId;
269-
lastApplyLogId_ = committedLogId;
270-
persist(committedLogId, committedLogTerm, lastApplyLogId_);
271-
lastApplyTime_ = time::WallClock::fastNowInMilliSec();
272-
LOG(INFO) << folly::sformat(
273-
"Commit snapshot to : committedLogId={},"
274-
"committedLogTerm={}, lastApplyLogId_={}",
275-
committedLogId,
276-
committedLogTerm,
277-
lastApplyLogId_);
278-
}
279-
return {nebula::cpp2::ErrorCode::SUCCEEDED, count, size};
280-
}
281164

282165
void Listener::resetListener() {
283166
std::lock_guard<std::mutex> g(raftLock_);

src/kvstore/Listener.h

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "common/base/Base.h"
1010
#include "common/meta/SchemaManager.h"
1111
#include "kvstore/Common.h"
12+
#include "kvstore/LogEncoder.h"
1213
#include "kvstore/raftex/Host.h"
1314
#include "kvstore/raftex/RaftPart.h"
1415
#include "kvstore/wal/FileBasedWal.h"
@@ -180,14 +181,6 @@ class Listener : public raftex::RaftPart {
180181
*/
181182
virtual LogID lastApplyLogId() = 0;
182183

183-
/**
184-
* @brief Apply data into listener's state machine
185-
*
186-
* @param data Key/value to apply
187-
* @return True if succeed. False if failed.
188-
*/
189-
virtual bool apply(const std::vector<KV>& data) = 0;
190-
191184
/**
192185
* @brief Persist commitLogId commitLogTerm and lastApplyLogId
193186
*/
@@ -272,31 +265,13 @@ class Listener : public raftex::RaftPart {
272265
ClusterID clusterId,
273266
folly::StringPiece log) override;
274267

275-
/**
276-
* @brief If the listener falls behind way to much than leader, the leader will send all its data
277-
* in snapshot by batch, listener need to implement this method to apply the batch to state
278-
* machine. The return value is a pair of <logs count, logs size> of this batch.
279-
*
280-
* @param data Data to apply
281-
* @param committedLogId Commit log id of snapshot
282-
* @param committedLogTerm Commit log term of snapshot
283-
* @param finished Whether spapshot is finished
284-
* @return std::tuple<nebula::cpp2::ErrorCode, int64_t, int64_t> Return {ok, count, size} if
285-
* succeed, else return {errorcode, -1, -1}
286-
*/
287-
std::tuple<nebula::cpp2::ErrorCode, int64_t, int64_t> commitSnapshot(
288-
const std::vector<std::string>& data,
289-
LogID committedLogId,
290-
TermID committedLogTerm,
291-
bool finished) override;
292-
293268
/**
294269
* @brief Background job thread will trigger doApply to apply data into state machine periodically
295270
*/
296271
void doApply();
297272

298273
// Process logs and then call apply to execute
299-
virtual void processLogs();
274+
virtual void processLogs() = 0;
300275

301276
protected:
302277
LogID leaderCommitId_ = 0;

src/kvstore/plugins/elasticsearch/ESListener.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
DECLARE_uint32(ft_request_retry_times);
1212
DECLARE_int32(ft_bulk_batch_size);
13+
DEFINE_int32(listener_commit_batch_size, 1000, "Max batch size when listener commit");
1314

1415
namespace nebula {
1516
namespace kvstore {
@@ -244,5 +245,122 @@ bool ESListener::writeDatum(const std::vector<nebula::plugin::DocItem>& items) c
244245
return true;
245246
}
246247

248+
void ESListener::processLogs() {
249+
std::unique_ptr<LogIterator> iter;
250+
{
251+
std::lock_guard<std::mutex> guard(raftLock_);
252+
if (lastApplyLogId_ >= committedLogId_) {
253+
return;
254+
}
255+
iter = wal_->iterator(lastApplyLogId_ + 1, committedLogId_);
256+
}
257+
258+
LogID lastApplyId = -1;
259+
// the kv pair which can sync to remote safely
260+
std::vector<KV> data;
261+
while (iter->valid()) {
262+
lastApplyId = iter->logId();
263+
264+
auto log = iter->logMsg();
265+
if (log.empty()) {
266+
// skip the heartbeat
267+
++(*iter);
268+
continue;
269+
}
270+
271+
DCHECK_GE(log.size(), sizeof(int64_t) + 1 + sizeof(uint32_t));
272+
switch (log[sizeof(int64_t)]) {
273+
case OP_PUT: {
274+
auto pieces = decodeMultiValues(log);
275+
DCHECK_EQ(2, pieces.size());
276+
data.emplace_back(pieces[0], pieces[1]);
277+
break;
278+
}
279+
case OP_MULTI_PUT: {
280+
auto kvs = decodeMultiValues(log);
281+
DCHECK_EQ(0, kvs.size() % 2);
282+
for (size_t i = 0; i < kvs.size(); i += 2) {
283+
data.emplace_back(kvs[i], kvs[i + 1]);
284+
}
285+
break;
286+
}
287+
case OP_REMOVE:
288+
case OP_REMOVE_RANGE:
289+
case OP_MULTI_REMOVE: {
290+
break;
291+
}
292+
case OP_BATCH_WRITE: {
293+
auto batch = decodeBatchValue(log);
294+
for (auto& op : batch) {
295+
// OP_BATCH_REMOVE and OP_BATCH_REMOVE_RANGE is igored
296+
if (op.first == BatchLogType::OP_BATCH_PUT) {
297+
data.emplace_back(op.second.first, op.second.second);
298+
}
299+
}
300+
break;
301+
}
302+
case OP_TRANS_LEADER:
303+
case OP_ADD_LEARNER:
304+
case OP_ADD_PEER:
305+
case OP_REMOVE_PEER: {
306+
break;
307+
}
308+
default: {
309+
VLOG(2) << idStr_ << "Unknown operation: " << static_cast<int32_t>(log[0]);
310+
}
311+
}
312+
313+
if (static_cast<int32_t>(data.size()) > FLAGS_listener_commit_batch_size) {
314+
break;
315+
}
316+
++(*iter);
317+
}
318+
// apply to state machine
319+
if (lastApplyId != -1 && apply(data)) {
320+
std::lock_guard<std::mutex> guard(raftLock_);
321+
lastApplyLogId_ = lastApplyId;
322+
persist(committedLogId_, term_, lastApplyLogId_);
323+
VLOG(2) << idStr_ << "Listener succeeded apply log to " << lastApplyLogId_;
324+
lastApplyTime_ = time::WallClock::fastNowInMilliSec();
325+
}
326+
}
327+
328+
std::tuple<nebula::cpp2::ErrorCode, int64_t, int64_t> ESListener::commitSnapshot(
329+
const std::vector<std::string>& rows,
330+
LogID committedLogId,
331+
TermID committedLogTerm,
332+
bool finished) {
333+
VLOG(2) << idStr_ << "Listener is committing snapshot.";
334+
int64_t count = 0;
335+
int64_t size = 0;
336+
std::vector<KV> data;
337+
data.reserve(rows.size());
338+
for (const auto& row : rows) {
339+
count++;
340+
size += row.size();
341+
auto kv = decodeKV(row);
342+
data.emplace_back(kv.first, kv.second);
343+
}
344+
if (!apply(data)) {
345+
LOG(INFO) << idStr_ << "Failed to apply data while committing snapshot.";
346+
return {
347+
nebula::cpp2::ErrorCode::E_RAFT_PERSIST_SNAPSHOT_FAILED, kNoSnapshotCount, kNoSnapshotSize};
348+
}
349+
if (finished) {
350+
CHECK(!raftLock_.try_lock());
351+
leaderCommitId_ = committedLogId;
352+
lastApplyLogId_ = committedLogId;
353+
persist(committedLogId, committedLogTerm, lastApplyLogId_);
354+
lastApplyTime_ = time::WallClock::fastNowInMilliSec();
355+
LOG(INFO) << folly::sformat(
356+
"Commit snapshot to : committedLogId={},"
357+
"committedLogTerm={}, lastApplyLogId_={}",
358+
committedLogId,
359+
committedLogTerm,
360+
lastApplyLogId_);
361+
}
362+
return {nebula::cpp2::ErrorCode::SUCCEEDED, count, size};
363+
}
364+
247365
} // namespace kvstore
248366
} // namespace nebula

src/kvstore/plugins/elasticsearch/ESListener.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class ESListener : public Listener {
7171
* @param data Key/value to apply
7272
* @return True if succeed. False if failed.
7373
*/
74-
bool apply(const std::vector<KV>& data) override;
74+
bool apply(const std::vector<KV>& data);
7575

7676
/**
7777
* @brief Persist commitLogId commitLogTerm and lastApplyLogId
@@ -92,6 +92,14 @@ class ESListener : public Listener {
9292
*/
9393
LogID lastApplyLogId() override;
9494

95+
void processLogs() override;
96+
97+
std::tuple<nebula::cpp2::ErrorCode, int64_t, int64_t> commitSnapshot(
98+
const std::vector<std::string>& data,
99+
LogID committedLogId,
100+
TermID committedLogTerm,
101+
bool finished) override;
102+
95103
private:
96104
/**
97105
* @brief Write last commit id, last commit term, last apply id to a file

0 commit comments

Comments
 (0)