Hypertable源码解读之数据写入客户端逻辑

来源:互联网 发布:js手动触发resize事件 编辑:程序博客网 时间:2024/05/17 06:27
数据写入逻辑分为客户端和服务器端,下面简述客户端逻辑。
客户端缓存需要写入的cell集合,按其key所属的rangeserver进行区分,即将key落入同一rangeserver的cell分为一组,每组又按照不同的range进行区分。当commit时,隶属不同rangeserver的cell集合将被异步的发送到对应的rangeserver。客户端只有等到所有异步请求的响应之后,才能进行下一轮的写入处理。
客户端在写入前会打开表,并创建一个TableMutator对象。每个mutator对象对应一个TableMutatorAsync对象,即表示写入将异步的执行。TableMutatorAsync对象对应了多个TableMutatorAsyncScatterBuffer对象,这些对象中只有一个表示尚未commit的一批cell,其名称为m_current_buffer,其余都表示已经commit但尚未获得服务器端成功响应的cell集合。这三个对象之间共享同一个应用程序队列和回调对象(TableCallback)。
客户端在插入cell集合时,会交给TableMutator.set_cells函数,该函数又转交给TableMutatorAsync.set_cells函数。此函数中,会序列化每个cell为key/value的字节流,然后交由TableMutatorAsyncScatterBuffer.set函数,此函数中,根据key.row获取该cell应该插入的range所在的rangeserver,为每个rangeserver创建一个TableMutatorAsyncSendBuffer对象,并将序列化的cell存入该对象。
客户端在commit cell集合时,会交给TableMutator.flush函数,该函数又转交给TableMutatorAsync.flush_with_tablequeue函数。此函数中,会交由TableMutatorAsyncScatterBuffer.send函数去执行提交操作,然后记录当前TableMutatorAsyncScatterBuffer对象(m_current_buffer)及其编号到未完成的buffer集合(m_outstanding_buffer)中,并创建新的TableMutatorAsyncScatterBuffer对象,置其编号为之前编号加1。
TableMutatorAsyncScatterBuffer.send函数中处理每个rangeserver对应的TableMutatorAsyncSendBuffer对象。从其获取所有的cell,按照key排序后重新序列化,发送一个update请求到对应的rangeserver。每次的发送将会创建一个TableMutatorAsyncDispatchHandler回调对象异步的接收服务器端的响应。
服务器端如果对于本次update请求产生响应,回调对象将添加一个TableMutatorAsyncHandler对象到应用程序队列。队列的值守线程获取到该对象后会调用其run函数。其中将获取到本次update请求的TableMutatorAsyncScatterBuffer对象,并调用其finish函数去清理客户端的记录。
TableMutatorAsyncScatterBuffer.finish函数将调用TableMutatorAsync.buffer_finish函数。后者将会从未完成的buffer集合中移除本次update请求,即buffer编号及其对应的TableMutatorAsyncScatterBuffer对象。后者还会调用回调对象(TableCallback)的update_ok函数,该函数其实调用了TableMutator.update_ok函数。
至此,客户端完成了写入流程结束。可以看到,从TableMutator开始,又从TableMutator结束,正好形成了一个闭环。
0 0