重新说明:Namenode的双缓冲机制和分段加锁原理

1,440 阅读2分钟

双缓冲机制和分段加锁

我们需要从Namenode的双缓冲机制说起,会有3个标志

isAutoSyncScheduled:判断是否在进行缓存交换

synctxid:这是线程进行磁盘刷写的事务id

isSyncRunning:是否在进行写磁盘

分析过程

线程1会先获取锁,然后会看看当前有没有在交换缓存(这里通过isAutoSyncScheduled来判断),如果没有,就去获取一个全局唯一的事务ID,这个ID是递增的。拿到事务ID后,就开始写入bufCurrent,写完后判断bufCurrent是否超过了512k,如果没有,线程1的流程就结束了,由于线程2,3,4在线程1没释放锁的时候,都会一直等待,如果线程2,3,4拿到了锁,也会继续上面线程1的操作。

我们假设线程4写完后,发现bufCurrent内存超过了512k,此时就会把isAutoSyncScheduled设置为true,说明要开始交换内存了,其他线程就不能做以上的操作了。这里的bufCurrent就是线程1,2,3,4写入的数据。

此时如果线程4写完,发现bufCurrent已经超过512k了,那就会把isAutoSyncScheduled设置为true,说明要开始交换内存了

此时线程5可以正常获取到锁,然后进行判断,isAutoSyncScheduled为true,那它就要wait,此时交换完内存之后,bufCurrent的内存就清空了,把isSyncRunning设置true,然后isAutoSyncScheduled设置为false,然后唤醒wait的线程。

线程4唤醒其他线程后,他就开始把bufReady的数据写入磁盘,这个操作是很耗时的,所以并没有加锁,但是它是运行状态,所以下图标记为绿色。这里的bufReady就是线程1,2,3,4写入的数据。此时是线程5获取了锁,发现内存交换完毕了,开始往bufCurrent写数据。

假如此时bufCurrent又超过了512k了,就会把isAutoSyncScheduled设置为true,说明打算交换内存,其他线程就不能往bufCurrent写入数据了。此时线程6拿到锁进来,但是它发现isAutoSyncScheduled为true,所以它就开始wait。

此时线程4写完了磁盘,然后他获取到锁,就会把synctxid更改为自己的事务ID,然后赋值isSyncRunning为false,说明磁盘写入完成了。最后唤醒wait的线程5。此时线程5重新拿回锁,发现isSyncRunning为false,那它就继续交换内存,交换完了之后,修改isAutoSyncScheduled回false,唤醒线程6,之后正常执行

以上就是双缓冲和分段加锁的东西