Code Monkey home page Code Monkey logo

kvstoragebaseraft-cpp's Introduction

Hi 👋

大家好,我是程序员Carl。哈工大师兄,ACM亚洲区域赛铜牌,毕业后在腾讯、百度采坑多年,以下资料会对大家很有帮助:

我的开源项目:

学习规划 🌱

开源项目 🔭

小游戏 😄

  • Gomoku:可联机对战的五子棋项目

开发的工具 📫

我的公众号⚡:

kvstoragebaseraft-cpp's People

Contributors

578223592 avatar hero-heng avatar ildnyy avatar tinnnnnn avatar youngyangyang04 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

kvstoragebaseraft-cpp's Issues

环境配置过程分享|protoc muduo boost

分享一下我几经波折的环境配置过程,我觉得我踩了大部分的坑(一开始用的windows环境缺乏<sys/socket.h>)

0c8ab72d28a84959a32e710dad51ffcd
这里发现版本不合适,目前我的版本为libprotoc 3.19.1

项目的版本为

protoc --version                      
libprotoc 3.12.4

protoc安装传送门:https://github.com/protocolbuffers/protobuf/releases/tag/v3.12.4
boost muduo安装传送门: https://blog.csdn.net/qq_41453285/article/details/105104845

注意:对于muduo编译生成的静态文件需要移动到根目录下../build/release-cpp11/lib不然会报这个错误

cp build/release-cpp11/lib/*  /usr/lib

错误截图:
705377e39f4459e36a7f3856a1224bb

最后成功啦,成功的截图:

d7543819f14c13f22632cd15ef47c2b

653e5346486ec1e042280e776f1b6b5

feat:RPC自定义协议的头部字段长度优化

头部的_消息体长度_字段目前是固定4个字节,这个可能设计的不是很合理,考虑使用更灵活的方式。
可以参考protobuf的变长编码、Redis中的对于长度的变长编码,即用标志位来确定_消息体长度_,这样来节约RPC的长度

快照功能

在raft的代码里实现了快照功能,我们应该怎么在clerk中使用快照

make报错

您好,我在使用rpc时make出错
protobuf的版本 3.14.2 cmake版本3.22.6
image
muduo库已经链接到/usr/下,boost也已安装,但是在make时报错一些代码相关的错误,我并未修改过代码,报错如下
image
我看报错信息,使用的
image
我的g++和gcc版本是4.8.5的

编译出错

KVstorageBaseRaft-cpp-rpc/src/rpc/include/rpcheader.pb.h:10:10: fatal error: google/protobuf/port_def.inc: No such file or directory

宕机测试

我应该怎么模拟某个节点宕机的场景来测试程序

发起RPC请求失败| 可能ip地址问题

在执行完./provider后,在另一个终端执行。/consumer出现RPC请求失败
image
image
./provider后的ip是127.0.0.1但是./consumer的ip是127.0.1.1,是不能重开终端运行吗

请问这样算运行成功吗

provider文件运行如图
VUEP04C$6A}5Q@BD)B07D88

consumer文件运行如图
(YQ ~%_2%AF6R(L{G@R`C3S

raftCoreRun文件运行如图,且文件一直运行
S 4}E)9LQ~05C@1L3}ZR K2

callermain文件如图,且retrun到0
J86O1CJ9R~_1R9Z`96N}U

请问怎么分析火焰图

我导出了这个火焰图,这个图好像没有定量指标(只有定性占比),请问关于测试性能方面的话是怎么分析呢
image

未生成快照

Persister类里面的 long long m_raftStateSize; 其他函数里面没有及时更新,导致kvserver类里面的IfNeedToSendSnapShotCommand一直没被触发,是不是会导致不能生成快照,我本地跑起来,快照的txt文件也确实是空的,这个有什么考虑吗?

Get()长字符串出错

raft调试
这里没有使用跳表,而是将文件数据读取为字符串后进行传输。图片中是服务端的日志,一旦读取完数据进行传输就会提示is not leader,还有很长一段跟上图同样的日志信息,最终客户端等待长时间后会提示栈溢出。但是Put()该文件却能成功执行,不太清楚原因。

关于Raft测试

您好,想请问下从功能的角度怎么测试能证明本项目Raft分布式的正确性,有什么工具还是需要怎么实现呢

doc:在wiki界面加入debug的过程分析

2024-2-27:done,done:https://github.com/youngyangyang04/KVstorageBaseRaft-cpp/wiki/%E5%8D%8F%E7%A8%8B%E5%8A%A0%E5%85%A5%E7%9A%84%E5%8E%9F%E5%9B%A0%E5%92%8C%E8%BF%87%E7%A8%8B%E5%88%86%E4%BA%AB


相关issue:#16

相关资料:

这么改了之后虽然可行了,但是感觉没有用到协程的关键功能,即调度功能。

sylar协程库什么时候会切换协程?

一个任务执行完之后。

只是可以通过hook等技术来

那么对于当前来说,加不加入协程感觉作用都是一样的,只要再写一个定时器类就可以了。

硬要这么说感觉也是,这方面的说法一方面来说可以参考协程项目,另一方面来说引入这个可以后期引入更多的功能,

新发现:引入这个之后对原来的代码侵入更小,如果不用这个,那么要改动的就比较多了


在C++标准库中直接hook std::this_thread::sleep_for是不可行的,因为C++标准库的实现通常是由编译器提供的,而且C++标准库的行为是由C++标准规定的

因此只有libc里面的这些函数才能正常的hook


发现一个bug和优化点,感觉面试的时候可以讲一讲。

leaderHearBeatTicker() 设置睡眠时间为: 1189774 毫秒
leaderHearBeatTicker() 实际睡眠时间为: 1189.93 毫秒

发现睡眠的时间远远超过预期。

调整了:#39


发现使用IO-Manager管理之后,选举会超时。

选举之前的部分日志如下:

image

1.一直没有AE的日志

2.一直都是两个节点的HOOK日志

猜测:领导日志函数肯定在哪一块卡住了导致一直没有发送。

目前怀疑是睡眠的时候卡住了,明日对比下两个日志的数量和时间

image

2024-2-22:

使用atomic分析得出是睡眠时间过久,相关日志:

20 leaderHearBeatTicker();函数设置睡眠时间为: 24 毫秒
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [func-Raft::sendAppendEntries-raft{1}] leader 向节点{2}发送AE rpc開始 , args->entries_size():{0}
[2024-2-22-20-39-29] [func-Raft::sendAppendEntries-raft{1}] leader 向节点{0}发送AE rpc成功
[2024-2-22-20-39-29] ---------------------------tmp------------------------- 節點{0}返回true,當前*appendNums{2}
[2024-2-22-20-39-29] [func-Raft::sendAppendEntries-raft{1}] leader 向节点{2}发送AE rpc成功
[2024-2-22-20-39-29] ---------------------------tmp------------------------- 節點{2}返回true,當前*appendNums{1}
 electionTimeOutTicker();函数设置睡眠时间为: 5 毫秒
 electionTimeOutTicker();函数实际睡眠时间为: 4.63221 毫秒
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-29] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
 electionTimeOutTicker();函数设置睡眠时间为: 320 毫秒
 electionTimeOutTicker();函数实际睡眠时间为: 321.094 毫秒
HOOK USLEEP REAL START
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
 electionTimeOutTicker();函数设置睡眠时间为: 445 毫秒
 electionTimeOutTicker();函数实际睡眠时间为: 445.421 毫秒
HOOK USLEEP REAL START
HOOK USLEEP REAL START
HOOK USLEEP REAL START
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
[2024-2-22-20-39-30] [Raft::applierTicker() - raft{1}]  m_lastApplied{0}   m_commitIndex{0}
 electionTimeOutTicker();函数设置睡眠时间为: 72 毫秒
 electionTimeOutTicker();函数实际睡眠时间为: 73.5567 毫秒
[2024-2-22-20-39-30] [       ticker-func-rf(2)              ]  选举定时器到期且不是leader,开始选举 

[2024-2-22-20-39-30] [func-sendRequestVote rf{2}] 向server{2} 發送 RequestVote 開始
[2024-2-22-20-39-30] [func-sendRequestVote rf{2}] 向server{2} 發送 RequestVote 開始
HOOK USLEEP REAL START
[2024-2-22-20-39-30] [func-sendRequestVote rf{2}] 向server{2} 發送 RequestVote 完畢,耗時:{0} ms
[2024-2-22-20-39-30] [func-sendRequestVote rf{2}] elect success  ,current term:{2} ,lastLogIndex:{0}

[2024-2-22-20-39-30] [func-Raft::doHeartBeat()-Leader: {2}] Leader的心跳定时器触发了且拿到mutex,开始发送AE

[2024-2-22-20-39-30] [func-Raft::doHeartBeat()-Leader: {2}] Leader的心跳定时器触发了 index:{0}

[2024-2-22-20-39-30] [func-Raft::doHeartBeat()-Leader: {2}] Leader的心跳定时器触发了 index:{1}
[2024-2-22-20-39-30] [       ticker-func-rf(1)              ]  选举定时器到期且不是leader,开始选举 


[2024-2-22-20-39-30] [func-sendRequestVote rf{2}] 向server{2} 發送 RequestVote 完畢,耗時:{0} ms
[2024-2-22-20-39-30] [func-sendRequestVote rf{1}] 向server{3} 發送 RequestVote 開始
HOOK USLEEP REAL START
[2024-2-22-20-39-30] [func-Raft::sendAppendEntries-raft{2}] leader 向节点{0}发送AE rpc開始 , args->entries_size():{0}
[2024-2-22-20-39-30] [func-sendRequestVote rf{1}] 向server{3} 發送 RequestVote 開始
20 leaderHearBeatTicker();函数实际睡眠时间为: 347.828 毫秒

20 leaderHearBeatTicker();函数实际睡眠时间为: 347.828 毫秒中20是atomic的值,发现睡眠过久,排查一下。

发现发起不同选举的时候leader的异常(过长)时间前面的atomic都很有规律

20 40 39 59

39估计已经发生leader的变更了。


wiki必备元素:

  • 分析过程
  • 关键代码加入
  • 得到的教训:协程库使用要注意定时不准确,运行代码占有时间可能会导致其他定时的延时触发

编译

你好,我也是libprotoc 3.12.4,且moduo正确安装,cmake3.22.1,但是只编译到82%,还是会出现大量protoc的错误啊:
[ 82%] Linking CXX executable ../../../../bin/provider
/usr/bin/ld: CMakeFiles/provider.dir/friendService.cpp.o: in function void* google::protobuf::Arena::AllocateInternal<std::cxx11::basic_string<char, std::char_traits, std::allocator > >(bool)': /usr/local/include/google/protobuf/arena.h:536: undefined reference to google::protobuf::Arena::AllocateAlignedNoHook(unsigned long)'
/usr/bin/ld: CMakeFiles/provider.dir/friendService.cpp.o: in function fixbug::GetFriendsListResponse::_internal_add_friendsabi:cxx11': /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.h:873: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::Add()'
/usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::ResultCode::_InternalParse(char const*, google::protobuf::internal::ParseContext*)': /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:230: undefined reference to google::protobuf::internal::InlineGreedyStringParser(std::cxx11::basic_string<char, std::char_traits, std::allocator >, char const, google::protobuf::internal::ParseContext*)'
/usr/bin/ld: /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:240: undefined reference to google::protobuf::internal::UnknownFieldParse(unsigned long, google::protobuf::UnknownFieldSet*, char const*, google::protobuf::internal::ParseContext*)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::ResultCode::_InternalSerialize(unsigned char*, google::protobuf::io::EpsCopyOutputStream*) const':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:275: undefined reference to google::protobuf::internal::WireFormat::InternalSerializeUnknownFieldsToArray(google::protobuf::UnknownFieldSet const&, unsigned char*, google::protobuf::io::EpsCopyOutputStream*)' /usr/bin/ld: CMakeFiles/provider.dir/
/friend.pb.cc.o: in function fixbug::ResultCode::ByteSizeLong() const':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:305: undefined reference to google::protobuf::internal::ComputeUnknownFieldsSize(google::protobuf::internal::InternalMetadata const&, unsigned long, google::protobuf::internal::CachedSize*)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListRequest::_InternalParse(char const*, google::protobuf::internal::ParseContext*)':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:454: undefined reference to google::protobuf::internal::UnknownFieldParse(unsigned long, google::protobuf::UnknownFieldSet*, char const*, google::protobuf::internal::ParseContext*)' /usr/bin/ld: CMakeFiles/provider.dir/
/friend.pb.cc.o: in function fixbug::GetFriendsListRequest::_InternalSerialize(unsigned char*, google::protobuf::io::EpsCopyOutputStream*) const':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:483: undefined reference to google::protobuf::internal::WireFormat::InternalSerializeUnknownFieldsToArray(google::protobuf::UnknownFieldSet const&, unsigned char*, google::protobuf::io::EpsCopyOutputStream*)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListRequest::ByteSizeLong() const':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:506: undefined reference to google::protobuf::internal::ComputeUnknownFieldsSize(google::protobuf::internal::InternalMetadata const&, unsigned long, google::protobuf::internal::CachedSize*)' /usr/bin/ld: CMakeFiles/provider.dir/
/friend.pb.cc.o: in function fixbug::GetFriendsListResponse::GetFriendsListResponse(google::protobuf::Arena*)':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:587: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::RepeatedPtrField(google::protobuf::Arena*)' /usr/bin/ld: /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:587: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::~RepeatedPtrField()'
/usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::GetFriendsListResponse(fixbug::GetFriendsListResponse const&)': /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:594: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::RepeatedPtrField(google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > > const&)'
/usr/bin/ld: /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:594: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::~RepeatedPtrField()' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::~GetFriendsListResponse()':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:609: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::~RepeatedPtrField()' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::Clear()':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:641: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::Clear()' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::_InternalParse(char const*, google::protobuf::internal::ParseContext*)':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:671: undefined reference to google::protobuf::internal::InlineGreedyStringParser(std::cxx11::basic_string<char, std::char_traits, std::allocator >, char const, google::protobuf::internal::ParseContext*)' /usr/bin/ld: /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:683: undefined reference to google::protobuf::internal::UnknownFieldParse(unsigned long, google::protobuf::UnknownFieldSet*, char const*, google::protobuf::internal::ParseContext*)'
/usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::_InternalSerialize(unsigned char*, google::protobuf::io::EpsCopyOutputStream*) const': /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:720: undefined reference to google::protobuf::internal::WireFormat::InternalSerializeUnknownFieldsToArray(google::protobuf::UnknownFieldSet const&, unsigned char*, google::protobuf::io::EpsCopyOutputStream*)'
/usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::ByteSizeLong() const': /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:737: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::size() const'
/usr/bin/ld: /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:738: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::size() const' /usr/bin/ld: /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:740: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::Get(int) const'
/usr/bin/ld: /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:751: undefined reference to google::protobuf::internal::ComputeUnknownFieldsSize(google::protobuf::internal::InternalMetadata const&, unsigned long, google::protobuf::internal::CachedSize*)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::MergeFrom(fixbug::GetFriendsListResponse const&)':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:781: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::MergeFrom(google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > > const&)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::InternalSwap(fixbug::GetFriendsListResponse*)':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:808: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::InternalSwap(google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >*)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::FiendServiceRpc::descriptor()':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:822: undefined reference to google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const*, bool)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function void* google::protobuf::Arena::AllocateInternalfixbug::ResultCode(bool)':
/usr/local/include/google/protobuf/arena.h:536: undefined reference to google::protobuf::Arena::AllocateAlignedNoHook(unsigned long)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function void* google::protobuf::Arena::AllocateInternalfixbug::GetFriendsListRequest(bool)':
/usr/local/include/google/protobuf/arena.h:536: undefined reference to google::protobuf::Arena::AllocateAlignedNoHook(unsigned long)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function void* google::protobuf::Arena::AllocateInternalfixbug::GetFriendsListResponse(bool)':
/usr/local/include/google/protobuf/arena.h:536: undefined reference to google::protobuf::Arena::AllocateAlignedNoHook(unsigned long)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function static_initialization_and_destruction_0(int, int)':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.cc:139: undefined reference to google::protobuf::internal::AddDescriptors(google::protobuf::internal::DescriptorTable const*)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function google::protobuf::io::EpsCopyOutputStream::EnsureSpace(unsigned char*)':
/usr/local/include/google/protobuf/io/coded_stream.h:690: undefined reference to google::protobuf::io::EpsCopyOutputStream::EnsureSpaceFallback(unsigned char*)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function google::protobuf::io::EpsCopyOutputStream::WriteStringMaybeAliased(unsigned int, std::cxx11::basic_string<char, std::char_traits, std::allocator > const&, unsigned char*)':
/usr/local/include/google/protobuf/io/coded_stream.h:719: undefined reference to google::protobuf::io::EpsCopyOutputStream::WriteStringMaybeAliasedOutline(unsigned int, std::cxx11::basic_string<char, std::char_traits, std::allocator > const&, unsigned char*)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function google::protobuf::internal::EpsCopyInputStream::DoneWithCheck(char const**, int)':
/usr/local/include/google/protobuf/parse_context.h:213: undefined reference to google::protobuf::internal::EpsCopyInputStream::DoneFallback(char const*, int)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function google::protobuf::internal::VarintParseSlow(char const*, unsigned int, unsigned int*)':
/usr/local/include/google/protobuf/parse_context.h:464: undefined reference to google::protobuf::internal::VarintParseSlow32(char const*, unsigned int)' /usr/bin/ld: CMakeFiles/provider.dir/
/friend.pb.cc.o: in function google::protobuf::internal::VarintParseSlow(char const*, unsigned int, unsigned long*)':
/usr/local/include/google/protobuf/parse_context.h:470: undefined reference to google::protobuf::internal::VarintParseSlow64(char const*, unsigned int)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function google::protobuf::internal::ReadTag(char const*, unsigned int*, unsigned int)':
/usr/local/include/google/protobuf/parse_context.h:511: undefined reference to google::protobuf::internal::ReadTagFallback(char const*, unsigned int)' /usr/bin/ld: CMakeFiles/provider.dir/
/friend.pb.cc.o: in function google::protobuf::internal::ReadSize(char const**)':
/usr/local/include/google/protobuf/parse_context.h:573: undefined reference to google::protobuf::internal::ReadSizeFallback(char const*, unsigned int)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::ResultCode::GetMetadataStatic()':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.h:180: undefined reference to google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const*, bool)' /usr/bin/ld: CMakeFiles/provider.dir/
/friend.pb.cc.o: in function fixbug::GetFriendsListRequest::GetMetadataStatic()':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.h:344: undefined reference to google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const*, bool)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::GetMetadataStatic()':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.h:481: undefined reference to google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const*, bool)' /usr/bin/ld: CMakeFiles/provider.dir/
/friend.pb.cc.o: in function fixbug::GetFriendsListResponse::_internal_friends_size() const':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.h:831: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::size() const' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function fixbug::GetFriendsListResponse::_internal_friendsabi:cxx11 const':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/example/rpcExample/friend.pb.h:844: undefined reference to google::protobuf::RepeatedPtrField<std::cxx11::basic_string<char, std::char_traits, std::allocator > >::Get(int) const' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function unsigned char* google::protobuf::io::EpsCopyOutputStream::WriteString<std::__cxx11::basic_string<char, std::char_traits, std::allocator > >(unsigned int, std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&, unsigned char*)':
/usr/local/include/google/protobuf/io/coded_stream.h:736: undefined reference to google::protobuf::io::EpsCopyOutputStream::WriteStringOutline(unsigned int, std::cxx11::basic_string<char, std::char_traits, std::allocator > const&, unsigned char*)' /usr/bin/ld: CMakeFiles/provider.dir//friend.pb.cc.o: in function void* google::protobuf::Arena::AllocateInternal<google::protobuf::internal::InternalMetadata::Containergoogle::protobuf::UnknownFieldSet >(bool)':
/usr/local/include/google/protobuf/arena.h:536: undefined reference to google::protobuf::Arena::AllocateAlignedNoHook(unsigned long)' /usr/bin/ld: ../../../../lib/librpc_lib.a(mprpcchannel.cpp.o): in function google::protobuf::io::EpsCopyOutputStream::WriteRaw(void const*, int, unsigned char*)':
/usr/local/include/google/protobuf/io/coded_stream.h:697: undefined reference to google::protobuf::io::EpsCopyOutputStream::WriteRawFallback(void const*, int, unsigned char*)' /usr/bin/ld: ../../../../lib/librpc_lib.a(rpcheader.pb.cpp.o): in function RPC::RpcHeader::_InternalParse(char const*, google::protobuf::internal::ParseContext*)':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/src/rpc/rpcheader.pb.cpp:182: undefined reference to google::protobuf::internal::InlineGreedyStringParser(std::__cxx11::basic_string<char, std::char_traits, std::allocator >, char const, google::protobuf::internal::ParseContext*)' /usr/bin/ld: /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/src/rpc/rpcheader.pb.cpp:191: undefined reference to google::protobuf::internal::InlineGreedyStringParser(std::__cxx11::basic_string<char, std::char_traits, std::allocator >, char const, google::protobuf::internal::ParseContext*)'
/usr/bin/ld: /home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/src/rpc/rpcheader.pb.cpp:210: undefined reference to google::protobuf::internal::UnknownFieldParse(unsigned long, google::protobuf::UnknownFieldSet*, char const*, google::protobuf::internal::ParseContext*)' /usr/bin/ld: ../../../../lib/librpc_lib.a(rpcheader.pb.cpp.o): in function RPC::RpcHeader::_InternalSerialize(unsigned char*, google::protobuf::io::EpsCopyOutputStream*) const':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/src/rpc/rpcheader.pb.cpp:249: undefined reference to google::protobuf::internal::WireFormat::InternalSerializeUnknownFieldsToArray(google::protobuf::UnknownFieldSet const&, unsigned char*, google::protobuf::io::EpsCopyOutputStream*)' /usr/bin/ld: ../../../../lib/librpc_lib.a(rpcheader.pb.cpp.o): in function RPC::RpcHeader::ByteSizeLong() const':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/src/rpc/rpcheader.pb.cpp:282: undefined reference to google::protobuf::internal::ComputeUnknownFieldsSize(google::protobuf::internal::InternalMetadata const&, unsigned long, google::protobuf::internal::CachedSize*)' /usr/bin/ld: ../../../../lib/librpc_lib.a(rpcheader.pb.cpp.o): in function void* google::protobuf::Arena::AllocateInternalRPC::RpcHeader(bool)':
/usr/local/include/google/protobuf/arena.h:536: undefined reference to google::protobuf::Arena::AllocateAlignedNoHook(unsigned long)' /usr/bin/ld: ../../../../lib/librpc_lib.a(rpcheader.pb.cpp.o): in function __static_initialization_and_destruction_0(int, int)':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/src/rpc/rpcheader.pb.cpp:95: undefined reference to google::protobuf::internal::AddDescriptors(google::protobuf::internal::DescriptorTable const*)' /usr/bin/ld: ../../../../lib/librpc_lib.a(rpcheader.pb.cpp.o): in function RPC::RpcHeader::GetMetadataStatic()':
/home/dai/Study_Linux/c++cpp/rpc分布式/KVstorageBaseRaft-cpp-main/src/rpc/include/rpcheader.pb.h:171: undefined reference to `google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const*, bool)'
collect2: error: ld returned 1 exit status
make[2]: *** [example/rpcExample/callee/CMakeFiles/provider.dir/build.make:100:../bin/provider] 错误 1
make[1]: *** [CMakeFiles/Makefile2:585:example/rpcExample/callee/CMakeFiles/provider.dir/all] 错误 2
make: *** [Makefile:84:all] 错误 2

请问这怎么解决呢

branch问题

思无邪大佬你好,请问4个branch之间的区别是什么呢?我学过rpc,看过一点raft算法的博客,该看哪个branch上手快一点呢?

后续任务,欢迎参与

项目目前主体已经完成。
还需要一些优化,包括但不限于:性能优化,更优雅的函数实现。具体的优化会以issue的方式提出。

也欢迎大家在issue提出问题和pr提出自己的改进方案。

目前项目各个部分考虑都不是很精细,是最好参与的时间节点,走过路过不容错过吼吼

目前已有的任务如下,欢迎大家来认领并完成,如果想完成但是有困难,我也会提供帮助,在对应issue链接下面评论即可。
也可以在这里提出可以改进的想法

现有任务列表:

Raft::RequestVote中的getLastLogIndex()函数返回值

先进入getLastLogIndex()函数:
image
然后看接收变量:
image
其实就算这样写,对程序也是没有影响的,因为涉及到lastLogTerm的那个if下面什么也没做,源代码是注释了那个DPrintf函数的,但是可以为了严谨改一下

doc:贡献指南

至少包含内容:

  • 代码提交需要format
  • 如何进行代码format

feat:线程池可否引入

目前发送RPC的时候每有一个其他节点都是猛起一个线程,一直等待RPC处理直到返回。
这样的话是不是不优雅,
1.对于起线程也许考虑更好的方式,可能是线程池。
2.对于RPC,也许设置一个超时返回时间比较合适。

参考:
braft库 and so on.

注意:要求加入的线程池需要有超时策略,即超时不阻塞。
而定时时间也是一个值得考量

make命令无法正常运行|版本问题

您好,我在执行make命令时会产生大量报错,在其他的代码上没有出现过这种现象。上网搜索了下原因,可能是与protobuf库相关,也许是版本与代码不兼容等问题,我尝试着重新安装了protobuf,但make命令仍然报错,请问应该怎么解决这个问题,能否给我一些建议呢。

ubantu版本:Ubuntu 20.04.6 LTS
cmake版本:3.28.1

下面是部分报错内容:
[ 3%] Building CXX object CMakeFiles/skip_list_on_raft.dir/src/rpc/mprpcchannel.cpp.o
In file included from /usr/include/google/protobuf/map_entry_lite.h:36,
from /usr/include/google/protobuf/generated_message_table_driven.h:35,
from /home/zhaozhuo/code/git/KVstorageBaseRaft-cpp/src/rpc/include/rpcheader.pb.h:26,
from /home/zhaozhuo/code/git/KVstorageBaseRaft-cpp/src/rpc/mprpcchannel.cpp:3:
/usr/include/google/protobuf/stubs/casts.h: In function ‘To google::protobuf::internal::bit_cast(const From&)’:
/usr/include/google/protobuf/stubs/casts.h:118:25: error: ‘bit_cast_with_different_sizes’ was not declared in this scope
118 | bit_cast_with_different_sizes);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/google/protobuf/stubs/casts.h:117:3: error: there are no arguments to ‘GOOGLE_COMPILE_ASSERT’ that depend on a template parameter, so a declaration of ‘GOOGLE_COMPILE_ASSERT’ must be available [-fpermissive]
117 | GOOGLE_COMPILE_ASSERT(sizeof(From) == sizeof(To),
| ^~~~~~~~~~~~~~~~~~~~~

image

make时报错

命令行无法直接安装protoc,我根据官方教程由源码编译安装了protoc-3.12.4
image
但是报了这个错误:
image
我看这个报错与安装muduo库时未将lib文件夹内容复制进usr/lib时的报错类似,但我在编译protoc时使用了bazel编译,没有对应的lib文件夹

feat:日志更优雅的实现

现有的方式是直接打到命令行,这样的方式不优雅也不合适

推荐方案:

  • 自己实现一个简单的日志,可以参考sylar中的日志实现
  • 引入现有的日志库,比如spdlog、glog

看这里:版本问题|环境配置问题|编译报错|杂项

首先确保你已经阅读过README中的相关安装内容。
其次可以参考下面的关于环境配置的issue。(如果有没有在列表的issue麻烦提醒我)


问题:
[不推荐]如果你尝试重新生成xxx.pb.cc文件,发现文件有改动,大概率是版本不一样,可以参考:#8 (comment)

feat:协程引入以减少线程数量

本仓库目前81280b5
在raft节点这一层要启动的线程有:
Raft::leaderHearBeatTicker():负责循环发送心跳和日志

Raft::electionTimeOutTicker():负责循环的发起选举

Raft::applierTicker():负责循环的写kv(通过向applyChan不断地提交日志代码

那么,对于这三个线程,经常要做的事情就是不停的sleep,导致白白的浪费了三个线程,这时候是不是就可以用协程代替这三个线程。
这样就可以节约线程数量了。

可能需要注意的问题:

1.正确性:注意协程的调度时间的控制,因为对于选举和心跳来说,都有超时的机制,如果超时又会发起新的选举,对于applierTicker()来说还好,只是会影响提交效率,最起码不会影响正确性。

但是对于选举和心跳,其并不能严格保证定时的唤醒时间的话可能会导致频繁的触发。因此在使用协程库的时候需要注意这一点,先测试下时间再看下,可能涉及对选举时间和心跳时间做一些改进。

待学习:

  • 目前这种std::thread::sleep()能保证严格的唤醒时间吗?
    A:精度应该是够的,sleep和std::thread::sleep()的精度在ms级别,单位也是ms,usleep的精度是微妙,虽然单位是us。

  • 前面提到了“节约线程数量”,那么这样频繁睡眠的线程和线程数量过多的话会有什么不利的影响吗?
    A:回答来自GPT:


频繁的睡眠和线程数量过多可能会对系统的性能和资源利用产生不利影响。在计算机编程中,线程是用于并发执行的最小单位,而睡眠通常是用于暂停线程的执行一段时间。

以下是频繁睡眠和过多线程可能带来的一些不利影响:

性能下降: 频繁睡眠会导致线程在执行过程中频繁地暂停和恢复,这会增加上下文切换的开销,并降低系统的整体性能。

资源浪费: 过多的线程会占用系统资源,包括内存和CPU时间片等。即使这些线程在某些时候处于睡眠状态,它们仍然会占用资源,导致资源浪费。

竞争条件和死锁: 过多的线程可能导致竞争条件和死锁。竞争条件是指多个线程竞争访问共享资源时可能出现的不确定行为。而死锁则是指多个线程互相等待对方释放资源而导致的僵局。

复杂性增加: 过多的线程会增加系统的复杂性,使得代码更难以理解、调试和维护。

内存消耗增加: 每个线程都需要一定量的内存来存储其状态信息。过多的线程会增加系统的内存消耗。

因此,在设计和实现多线程应用程序时,需要权衡线程数量和频繁睡眠的情况,以充分利用系统资源并确保良好的性能和可维护性。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.