ceph OSD读写流程(2)–主OSD的写操作事务的处理

journal-trans

  • OSD中写操作的处理中涉及到很多回调函数(这也是ceph本身的一个特点),这些回调函数追溯到Context类,这个类是回调函数类的抽象基类,继承它的类只需要在子类中实现它的finish函数,然后再finish函数中调用自己注册的回调函数,就能完成回调;
  • 上面说到的调用Context类的finish函数就能进行回调,那么具体调用它的地方就在Finisher类的finisher_thread_entry里,这个是finisher的线程处理函数,并且finisher还有一个finisher_queue,实现生产者消费者模型,生产者往finisher_queue里放东西,并通过条件变量通知finisher的线程处理函数来进行处理,在这个线程处理函数里就能通过调用Context类的complete函数,然后调用掉其子类实现的finish函数,从而完成回调的处理;
  • OSD的写操作先放到writeq里,通知FileJournal的线程处理函数进行写journal的处理,然后再放入到journal的finisher_queue里,然后对应的finisher线程处理函数调用之前注册的回调函数(C_JournaledAhead对应的函调函数是FileStore::_journaled_ahead)进行处理,这里就分成两条线路进行下去:
    • 放入ondisk_finisher,进而触发ondisk_finisher的线程处理函数进行处理,就会调用到C_OSD_OnOpCommit的函调函数ReplicatedBackend::op_commit,在这里面会检查waiting_for_commit是否为空(如果是3副本,这里面就有3项,每完成一个副本的写journal操作,就会从waiting_for_commit里删除一个),如果为空,才调用C_OSD_RepopCommit的回调函数repop_all_committed,从而调用ReplicatePG::eval_repop发给客户端写操作完成;
    • 放入op_wq里,FileStore::op_tp线程池就会从op_wq中取出进行操作,在FileStore::OpWQ::_process去进行写到本地缓存的操作(FileStore::_write),并且在完成后FileStore::OpWQ::_process_finish中处理,类似的也是放到一个finisher_queue里(op_finisher),然后finisher的线程调用C_OSD_OnOpApplied的回调函数(ReplicatedBackend::op_applied)来处理,如果waiting_for_applied为空(如果是3副本,这里面就有3项,每完成一个副本的写本地操作,就会从waiting_for_applied里删除一个),才调用C_OSD_RepOpApplied的回调函数repop_all_applied,进而调用ReplicatePG::eval_repop发给客户端数据可读;