PhxPaxos 源码阅读笔记(零)

前言

其实之前就很想阅读 PhxPaxos 的源码来加深一下自己对 Paxos 的理解,但因为中途出差一个月加上前前后后的相关准备就搁置了,对于 Paxos 的理解一直停留在纸面上。最近阿里的 X-Paxos 宣传的很火,而自己也稍微闲了一些,就准备把阅读源码这个坑给填了。

PhxPaxos 的整体代码量不是很大,注释虽然不多,但是可读性还是非常高的,配合着那些日志代码以及官方博客中的模型介绍,基本上可以很容易地理解它的大部分内容。

利用零零碎碎的晚上休息时间,大概用了快一周把代码读完了,就想着反正自己从中也学到了不少内容,干脆写一个系列的阅读笔记吧。这是我第一次尝试写一个系列,希望能够写的稍微有点条理吧,这篇博客算是挖坑了。不过最近依旧比较忙,尽可能保持比较快的速度更新吧。

前置内容

我自己并不是一上来就试图通过阅读 PhxPaxos 来理解 Paxos 的,所以肯定是必须有前置内容的,希望对本系列感兴趣的读者能够先看完下面这些相关的内容(如果后续某篇文章与前置内容无关的话,我会在文章开头标注)。

PhxPaxos 作者之一对于 Paxos 的介绍,至少读完前两篇:

  1. Paxos理论介绍(1): 朴素Paxos算法理论推导与证明
  2. Paxos理论介绍(2 ...
阅读全文

同步请求响应的实现

声明:本文代码均为 C++ 伪代码,仅用于表示含义,出于描述简单,语法使用 C++11。

最近在接手的工作中发现了一段有点问题的代码,功能上大致是要实现这样的目标:客户端发送一个请求,然后在当前线程内等待服务器的响应,但由于底层使用的网络库是异步 Reactor 模式的,需要进行一个基本的同步操作来实现发送线程内接收响应。以伪代码的形式表现大概如下:

struct Packet {};

class Synchronizer {};

void SendRequest(Packet *_req)
{
    unsigned int threadId = ::GetCurrentThreadId();
    _req->threadId = threadId;
    network->SendData(target, _req);

    Synchronizer::GetInstance()->RegisterThread(threadId);
    Packet *res = Synchronizer::GetInstance()->WaitThreadData(threadId);
}

显然,WaitThreadData 的操作不能因为收不到对端响应就一直阻塞 ...

阅读全文

内存模型引发的思考

昨天在看《深入理解 Java 虚拟机》,本来以为 12 章讲的内存模型指的是类似 C++ 对象模型的概念,可以在一个半小时内搞定,结果看到硬件上的一致性以及内存模型的概念时就发现触及自己的知识盲区了。

CPU 缓存一致性

首先是 CPU 缓存一致性,借一下书上的图。

现在的 CPU 基本上都是多核了,以 Intel i7 系列的处理器来说,每个核都有各自的寄存器组、L1 Cache、L2 Cache,多个核共享 L3 Cache,这里我们把 L1 和 L2 合起来统称为各个核的高速缓存。显然,各个核之间的高速缓存需要同步,否则如果两个核访问同一块内存时,就可能出现错误,因为它们对该内存的读写操作是直接作用于自己的高速缓存,而非主存,这就引入了 CPU 的缓存一致性协议。

我对这块并没有了解过,在网上搜了一下,找到了一篇感觉还不错的文章:缓存一致性 ...

阅读全文