还是假设某台机器(图中的machine)在数据库的原始数据是 d0,上图的处理流程变成了:
t1 时刻,有两个数据源的数据 d1,d2 同时到达数据处理层,主进程分配了线程 Merge1 处理 d1,线程 Merge2 处理 d2,两者又同时尝试从 redis 获得锁
t2 时刻,Merge1 成功获得了锁,同时从数据库中加载 machine 的原始数据 d0,Merge2 循环等待 Merge1 释放锁
t3 时刻,Merge1 合并完数据,并将合并好的数据 d0 + d1 存放到数据库,最后释放锁
t4 时刻,Merge2 获得了锁,同时从数据库中加载machine的数据 d0 + d1
t5 时刻,Merge2 合并完数据,并将合并好的数据 d0 + d1 + d2 存放到数据库,最后释放锁
从以上可以看到保持数据一致的原理其实也不难,无非就是使用一个键值来使得多个线程对同一台机器的数据的读写是同步的,但是在实现的过程中,往往会忽视了分布式锁所要具备的某个条件,极端情况下,还是会出现数据不一致的问题。
实现过程
结合以上的三种锁条件,下面我们将给出几种实现方式,来观察如果任意一个条件不满足,test_key的结果是否符合我们的预期。在实现的过程中将使用同一份测试用例。如下:
t1 时刻,有两个数据源的数据 d1,d2 同时到达数据处理层,主进程分配了线程 Merge1 处理 d1,线程 Merge2 处理 d2,两者又同时尝试从 redis 获得锁
t2 时刻,Merge1 成功获得了锁,同时从数据库中加载 machine 的原始数据 d0,Merge2 循环等待 Merge1 释放锁
t3 时刻,Merge1 合并完数据,并将合并好的数据 d0 + d1 存放到数据库,最后释放锁
t4 时刻,Merge2 获得了锁,同时从数据库中加载machine的数据 d0 + d1
t5 时刻,Merge2 合并完数据,并将合并好的数据 d0 + d1 + d2 存放到数据库,最后释放锁
从以上可以看到保持数据一致的原理其实也不难,无非就是使用一个键值来使得多个线程对同一台机器的数据的读写是同步的,但是在实现的过程中,往往会忽视了分布式锁所要具备的某个条件,极端情况下,还是会出现数据不一致的问题。
实现过程
结合以上的三种锁条件,下面我们将给出几种实现方式,来观察如果任意一个条件不满足,test_key的结果是否符合我们的预期。在实现的过程中将使用同一份测试用例。如下: