首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >内部分布式时间服务器实现

内部分布式时间服务器实现
EN

Stack Overflow用户
提问于 2014-02-27 10:18:14
回答 1查看 575关注 0票数 6

我已经为即将到来的分布式NoSQL数据库系统开发了一个内部分布式时间服务器(没有主服务器)。它应该处理拜占庭时钟和时钟倾斜问题,只要2/3在分布式系统中的时钟是正确的。

不过,我想看看其他人是如何实现这种模式的(对基于IEEE 1588的主/从模式实现不感兴趣)--更好的是一些已经在使用的开放源代码--断言我已经正确地实现了它,因为很难为它编写单元测试。

有人知道这样的开源实现吗?我们使用的编程语言是C++,所以我更喜欢C/C++引用,不过只要代码具有可读性,它可能就不那么重要了。

下面是到目前为止我的实现的代码(为了简单起见部分伪代码):

代码语言:javascript
复制
/*!
\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()));
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-07 17:18:27

在时间同步协议方面有相当多的文献,特别是在无线传感器网络中,在这种网络中,部署环境不适合时间主设备。关于this page的主题有一个很好的介绍。似乎最受关注的协议是洪泛时间同步协议(FTSP),它来自于马洛蒂、库西、西蒙和莱德奇( Lédeczi )的paper。我在TinyOS的wiki上描述了它的一个实现,它有您正在寻找的代码类型。

对于任何没有主从的系统,都要提出一个警告:没有“正确”时间的概念。您可以得到的最佳结果是节点收敛到公共时间引用。这是一个共识的时间,但不应该被认为是一个权威的“正确”的时间。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22065401

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档