内部分布式时间服务器实现
Internal Distributed Time Server implementation
我已经为我们即将推出的分布式NoSQL数据库系统制作了一个内部分布式时间服务器(没有母版)。它应该处理拜占庭时钟和时钟偏差问题,只要分布式系统中 2/3 的时钟是正确的。
然而,我想看看其他人如何实现这种模式(对基于 IEEE 1588 的主/从模式实现不感兴趣)——最好是一些已经在使用的开源代码——断言我已经正确实现了它,因为很难为它编写单元测试。
有谁知道这样的开源实现?我们使用的编程语言C++所以我更喜欢 C/C++ 引用,尽管只要代码是人类可读的,它可能并不那么重要。
以下是到目前为止我的实现的代码(为了简单起见,部分伪代码):
/*!
brief Maximum allowed clock skew in milliseconds
details A network node that has a clock skew greater than this value will be ignore
* and an error message will be logged
note Maximum divergence (drift) between two clocks on the network nodes will be 3x this amount if we
* have a worst case Byzantium clock issue
*/
#define MAX_ALLOWED_CLOCK_SCEW_MS 333
/*!
class CTimeServer
brief Internal distributed time server
details The time server frequently recieves the time from all the other master server nodes
* in the DBMS and calculates the current time by averaging all of the recieves timestamps.
note If a server node has a greater clock skew than c MAX_ALLOWED_CLOCK_SCEW_MS then it its
* timestamp is ignored and an error message is logged
note Clocks are accurately synchronized until more than 1/3 of the nodes have Byzantium clock issues
author Inge Eivind Henriksen
date February 2014
*/
class CTimeServer
{
private:
/** System offset in milliseconds */
std::atomic<int> offsetAverageMs;
/*!
brief Node offsets type
par key Node ID
par value Offset in milliseconds
*/
typedef std::map<int, int> nodeOffset_t;
/*!
brief Iterator type for c nodeOffset_t
relates nodeOffset_t
*/
typedef nodeOffset_t::iterator nodeOffsetIter_t;
/** Node offsets */
nodeOffset_t nodeOffsets;
/*!
brief Calculates the offset time in milliseconds between all the nodes in the distributed system
*/
int CalculateOffsetMs() {
bool exists;
nodeOffsetIter_t offsets_iter(&nodeOffsets);
int offsetMs = offsets_iter.first(&exists);
int averageMs = 0;
while (exists)
{
averageMs += offsetMs;
averageMs /= 2;
// Get the next file manager in the map
offsetMs = offsets_iter.next(&exists);
}
return averageMs;
}
public:
CTimeServer() {
offsetAverageMs = 0;
}
/*!
brief Register the time of a node
param nodeHostName [in] Network node host name or IP address
param nodeId [in] Network node ID
param timestamp [in] Network node timestamp
*/
void RegisterNodeTime(const wchar_t *nodeHostName, int nodeId, time_t timestamp) {
int now = (int)time(NULL);
int offset = (int)timestamp - now;
// Make sure the node clock is within the permitted values
if (abs(offset) > MAX_ALLOWED_CLOCK_SCEW_MS)
{
// Node clock skew was outside the permitted limit, so remove it from the list of valid time offsets
nodeOffsets.erase(nodeId);
// Throw an error
std::wstringstream err;
err << L"Network node " << nodeHostName << L" exceeded the maximum allowed clock skew of "
<< MAX_ALLOWED_CLOCK_SCEW_MS << L" ms by " << offset << " ms. Set the clock to correct this problem.";
throw err.str().c_str();
}
nodeOffsets.update(nodeId, offset);
// Recalculate the offset average
offsetAverageMs.store(CalculateOffsetMs());
}
/*!
brief Get the distributed system time
returns The distributed system time
*/
time_t GetTime() {
int now = (int)time(NULL);
return (time_t)(now + offsetAverageMs.load()));
}
在时间同步协议方面有相当多的文献,特别是对于无线传感器网络,其中部署环境不适合时间主控。此页面上对该主题进行了不错的介绍。似乎最受关注的协议是洪水时间同步协议(FTSP),来自Maróti,Kusy,Simon和Lédeczi的同名论文。我在其wiki上发现了TinyOS的实现,其中包含您正在寻找的代码类型。
对于任何无主系统,都有一个警告:没有"正确"时间的概念。你能得到的最好的结果是将节点收敛到一个公共时间参考。这是一个共识时间,但它不应该被认为是权威的"正确"时间。
相关文章:
- 为 Sql 服务器实现 odbc 包装器.将数据库数据读取为字符或要求驱动程序将数据转换为 C 类型
- 服务器端事件C++实现?
- 如何实现netconf+yangc++服务器
- 实现没有不安全服务器凭据的自定义 AuthMetadataProcessor
- 是否可以使用继承在C++中实现弹性云服务器?
- IPP 或 JetDirect 服务器实现
- BLE在Linux环境中使用C++的服务器端实现
- 在 FTP 服务器中正确实现 LIST 命令
- 内部分布式时间服务器实现
- 服务器在实现 POST 请求时响应字符串不完整
- 使用带有gsoap代理类的gsoap独立服务器实现http-get
- 如何使用套接字实现服务器客户端编程,在套接字中服务器向客户端发送消息而不从客户端获取请求
- 从头开始实现经典的OPC DA服务器
- 为什么我在尝试编译我的第一个 CORBA 服务器(使用 ACE/TAO ORB 实现)时遇到链接器错误
- 如何使用 JSON 实现带有 POCO C++ 网络库的 REST API 服务器
- 如何在Qt中编写客户端-服务器应用程序并实现简单的协议
- 使用多个线程在C++中实现客户端软件和服务器软件之间的通信
- 使用Java实现服务器应用程序和Matlab客户端之间的套接字通信
- PJSIP可以实现服务器端吗
- 实现服务器许可管理