文档章节

ceph的数据存储之路(5) -----osd数据处理

一只小江
 一只小江
发布于 2015/11/23 18:00
字数 3609
阅读 7859
收藏 6

osd的数据处理

当osd接管了来自rbd client发送的请求,在osd上进行解析,经过一系列的处理,最后保存到了osd的磁盘上。

 

上一节中讲述了rbdclient端是如何处理请求数据的,下面开始从osd接受数据开始进行讲述。

 

一、client如何与osd进行建立通信的呢?

1. osd是运行在服务器上的进程,进程的主体在ceph_osd.cc中的main函数开始,并且申请一些用于服务的线程。比如这里用于接客户端受连接的线程Accepter。如果配对连接成功后,会把连接成功的socket交给SimpleMessager来处理。

  

2. 在ceph_osd.cc 中main函数中 会申请一个Messager 消息管理的类,该类是一个基类,最终会选择SimpleMessager类实例,SimpleMessager类中会有一个叫做Accepter的成员,会申请该对象,并且初始化。

然后在main中把它绑定一个固定的ip,这个ip根据配置文件来获取。如0577行

 

3.这个ip最终会绑定在Accepter中。然后在Accepter->bind函数中,会对这个ip初始化一个socket,并且保存为listen_sd。接着会启动Accepter->start(),这里会启动Accepter的监听线程,这个线程做的事情放在Accepter->entry()函数中。接下来看看这个函数中实现了什么。

0216:开始一个循环,线程不能结束。知道停止这个线程时。

0218:poll监听一个端口,等待客户端来进行连接。

0219:如果有客户端来连接时,如果来接成功则进行下面的处理

0222:msgr 是具体实现类为SimpleMessager,跟踪到实现的函数中去。

0343:当接受到一个连接时,这时需要建立一个数据通道pipe,。

0344:告知pipe 处理socket为sd。也就是从这个sd读取数据。

0346:启动pipe的读线程,从sd中读取message信息。

0349:将pipe加入到SimpleMessager中的accepting_pipes,便于管理。

 

二、消息的传递

4. 接下来已经建立了pipe的通道,马上就要开始进行message的接受, 目前接收message的工作交给了pipe的reader线程。接下来看看pipe->reader()做了什么事情。

pipe->reader()中会先 read_message(),将传递的消息解析出来,然后把这个消息放入in_q->fast_dispatch(m)中处理,继续发送到OSD::ms_fast_dispatch中处理,在ms_fast_dispatch中会将message 转化为OpRequestRef op,后续直接对这个op进行处理。继续经过dispatch_session_waiting()、dispatch_op_fast()、handle_op()。handle_op()中开始将这个处理由OSD转化为PG的处理。

8502:根据message的信息可以获得pg_id。

8503:再根据pg_id可以恢复出pool的id。也就是pool的序号。

8508:根据当然获取到的osdmap重新修正这个pg_id。

8512:根据pg_id信息创建 pg的信息结构spg_t pgid。

 

三、消息的处理

5.上面已经根据message中的信息恢复出pg和pool的相关信息。这些信息对于osd组织数据有很大的帮助。接下来开始要交给PG进行处理了。

8568:根据pg_id在osd->pg_map中查找pg。这里要说明下PG是一个基类,由ReplicatedPG类实现。这里的PG实际上使用的就是继承类的方法。

8573:找到PG以后,这时将这个op交给PG进行继续处理。已经从OSD处理的message转化为了PG处理的op。由这里开始,最终添加到OSDService->op_wq队列,该队列是由OSD->ShardedOpWQ队列初始化,实际上是保存到了OSD-> 的ShardedOpWQ  ,然后保存在结构ShardData中等待被处理,然后唤醒处理这个队列的线程,线程处理函数OSD::ShardedOpWQ::_process调用到OSD::dequeue_op()、pg->do_request()、ReplicatedPG::do_request()、ReplicatedPG::do_op()。接下来看看do_op中是如何处理的。

 

1809:这里要创建一个OpContext结构,该结构会接管message中的所有ops的操作,ops的操作就是客户端将rbd请求拆分成object的请求。

 

四、形成事务Transaction

1810:获取一个transaction,因为pgbackend类被ReplicatedBackend类实现,所以get_transaction的实现由ReplicatedBackend::get_transaction() 完成,申请一个叫做RPGTransaction 然后交给了ctx->op_t。这里想要说明的是,申请了一个事物transaction,下面就要处理这个Transaction需要与我们的op组合了吧,在一个transaction中完成这些ops的操作,看看他们是如何关联的execute_ctx(),。

 

7. 首先使用int result = prepare_transaction(ctx); 他会将 ops上要写入的数据全部都按着结构保存在transaction的data_bl,op_bl中。拿着这个transaction 就已经获得了全部的操作和数据,这也就是将ops与Transaction绑定的结果。因为primary osd不仅仅是要自己保存数据,其他的replica osd也要保存数据的副本,这里有primary osd将准备好的数据发送给replica osd。

 

五、osd完成统计处理repop

2523:申请repop,这个repop是用来管理发送给其他副本以及自己进行数据处理的统计,根据这个结构可知那些osd都完成了数据的读写操作,回调比不可少的。

2528:issue_repop()将操作率先发给其他副本,这里其实就是与其他副本通信,将ops发送给其他副本,其他副本操作完成时能够及时的回调找到repop,然后开始处理,在issue_repop中规定了所有osd完成时的on_all_commit与on_all_applied的操作,并且将提交Transaction,使用函数submit_transaction()。这里pgbackend->submit_transaction()函数中,pgbackend对象已经被ReplicatedBackend进行了继承,所以最终使用的是ReplicatedBackend::submit_transaction()。

2530:如果数据处理完成了,使用eval_repop()进行收尾的工作,将结果回调给客户端。

 

8. 接下来继续查看函数void ReplicatedBackend::submit_transaction()中的实现方式

0590:开始准备一个处理操作的结构InProgressOp,然后将申请的on_all_commit、on_all_applied等回调操作进行统计。

0594:开始统计所有需要applied的副本操作数量,等待副本操作完成回调时进行清除,使用该结构方便统计是不是所有的副本都完成了操作。

0598:作用同0594相同,区别在于统计commit的副本操作数量。

0620:issue_op将ops的信息封装成message发送给replica osd副本的。这个操作就是在封装message,这里就不再多说了。

0619:开始记录本端操作object的log。这个log对于数据的恢复存在至关重要的决定。

0624:开始统计本端的sync回调,主要用于快照和克隆等等的数据同步。

0625:开始注册本端的applied回调函数,这里回调后会直接向上回调all_applied()

0627:开始注册本端删除object的回调操作函数(这个暂时不用考虑)。

0629:开始注册本端的commit回调函数,这里回调后直接向上回调all_commited()。

0631:本端开始真正的处理请求。这个parent指的就是ReplicaPG -> queue_transaction,然后在进行最后osd->store->queue_transaction ,这里的store是ObjectStore 几经辗转最后调用到继承类FileStore::queue_transactions()开始处理。

 

六、文件与日志的处理

9.从这里开始的 接下来就全部的交给了FileStore来处理了。

2071:在进行存储数据的时候 肯定是需要记录journal的,也就是当数据进行写入的时候需要写到journal中一份,当data数据失败的时候可以从journal中进行恢复。所以这里为了安全起见,一般都会采用journal的方式进行保存数据。

2082:如果选择的文件系统(如brfs)时,这种文件系统存在checkpoint机制时,可以采用的方法,可以并行的处理日志与data的写入操作。

2084:准备写入日志的操作_op_journal_transactions。

2086:准备写入数据的操作queue_op。

2088:当选择这条路时,这种文件系统不存在checkpoint机制,所以必须先写入日志,等待日志完成后才可以写入data。

2091:这时申请一个C_JournaledAhead的回调操作,这个操作会在日志完成之后进行回调处理处理时会将data写入磁盘。_op_journal_transactions()这里开始激发写入r日志的操作。

在_op_journal_transactions()中的处理操作如下图:

0266:判断自然要进行写入journal的。

0271:循环处理Transaction,当然此时假设只有一个Transaction。

0274:解析每一个Transaction的操作。

0278:获取每个操作的数据长度。

0279:获取每个操作的数据段偏移。

0281:将数据操作打包到内存tbl中形成日志数据。

0283:提交日志数据,完成下发任务journal->submit_entry,这里的journal由继承类FileJournal 实现的,所以这里继续调用FileJournal::submit_entry()。

1614:将申请的写日志完成的回调oncommit添加到completions队列中,等待写日志完成后开始调用,这里指的是C_JournaledAhead。

1618:如果当前的写操作队列没有可以处理的日志操作时,写操作线程应该处于睡眠的状态,所以需要唤醒这个写线程。

1620:开始唤醒写日志的线程。

1622:将本次需要写入的buffer统计到写线程的队列writeq中。

接下来就交给了写日志的线程FileJournal::write_thread_entry()中开始处理。这个写操作的线程就是要把数据写入到文件当中,完成后调取completions中对应的成员进行回调,然后调到C_JournaledAhead->finish() ,再进入FileStore::_journaled_ahead()中,这个函数分为了两个部分,一部分是将data操作提交到op_wq队列,另外一个就是对于journal操作完成的回调处理。

2178:将操作的op添加到FileStore:: op_wq中,然后等待写数据的线程将数据写入文件。

2181:先解析出在日志完成之后需要回调的那些操作,形成to_queue队列。

2187:如果这个to_queue队列不是空的队列,则交给ondisk_finisher队列进行处理。

2185:将日志保存完成的回调ondisk交给ondisk_finisher,后续有finisher线程处理,这里的ondisk注册回调为C_OSD_OnOpApplied。

 

 

10. 上面说道op_wq队列,将写data的操作加入到了op_wq中之后,这里会触发写data的线程。

data的写操作线程OpWQ::_process(),再调到FileStore::_do_op()函数中,再到FileStore::_do_transactions()函数、FileStore::_do_transaction()函数调用。

 

2529:这里解析这个操作,肯定是一个OP_write的操作。

2531:解析文件目录。

2532:解析文件的名字。

2533:解析要写入文件的位置。

2534:解析要写入文件的数据长度。

2537:解析要写入文件的数据。

2541:根据上面解析的信息,开始调用FileStore::_write 将数据真正的写入文件中的正确位置。当完成写任务后开始进行逐级回调。

OpWQ::_process()操作 对应的就是 FileStore::_finish_op()。在FileStore::_finish_op中主要做的就剩下一件事儿了,就是将请求进行回调处理。

1998:开始回调sync的操作,暂时没有涉及到快照克隆等 不需要考虑。

2001:准备开始回调onreadable的参数,这里回调注册的为C_OSD_OnOpCommit。

2002:进行其他操作的回调处理。

 

七、请求的回调处理

11. 到目前为止已经完成了journal的写入操作和data的写入操作。他们分别对应的回调为C_OSD_OnOpApplied,C_OSD_OnOpCommit。他们做的事情差不多,接下来先看看C_OSD_OnOpApplied的操作是怎样的

C_OSD_OnOpApplied->finish()  调取pg->op_applied(),最后到ReplicatedBackend::op_applied()

0667:开始删除在等待队列中的本端osd序号。这样表示本端已经处理完成了。

0670:检查是不是所有的等待在waiting_for_applied队列上的osd都完成了操作。这时可以进行完全回调。这里的on_applied注册的是C_OSD_RepopApplied回调。

0676:这里开始检查是不是所有的waiting_for_applied、waiting_for_commit队列中都已经处理完成则done成功,那时就可以删除in_progress_ops队列的ops了。

 

12. 接续C_OSD_RepopApplied 逐渐的想客户端进行调用。这里开始调用ReplicatedPG::repop_all_applied(),在这里会设置repop->all_applied 为ture。然后调用eval_repop进行处理。

7571:查看是否存在请求需要回调。

7574:开始循环处理这里的请求,然后将请求发还给客户端。

7578:恢复开始接收到请求的MOSDOp的操作。

7579:建议对应的应答消息,这个应答消息与接受到的请求相对应。

7582:将请求发还给客户端。

 

13. 以上就是整理osd来处理数据写操作请求的全部内容和流程了。

 

 

总结:

1.这里的流程太多了就不再细说了,请参考下面的全部结构图。

2.osd 预先运行进程 ceph_osd.cc中的main开始。

3.osd结构中申请了管理消息的SimpleMessager模块,该模块中存在一个叫做Accepter模块,该模块专门用来监听端口等待客户端进行连接的。然后交给reader,这时reader将已经建立的连接中开始读取message。

4.将message转化为OpRequest,并且交到dispath队列中。

5.由message等信息 转化得知pool信息和PG的信息,然后把message交给PG进行处理。

6.将OpRequest添加到osdservice->op_wq队列中,该队列中会有处理的线程,线程会将继续处理这个OpRequest的。

7.交给ReplicaPG处理 创建repop 所有的applied与commit的管理。

8.解析出OpRequest中的所有op与data。把这些数据用一个叫做Transaction的结构进行管理。

9.有transaction的处理开始,将replica osd的操作发送给副本。

10.本端开始处理journal的写入操作,加入到writeq队列,该队列有独立线程完成写入的操作。

11.写journal完成后,再将要写入的data添加到op_wq中,该队列同样存在一个线程进行处理,将数据最终的保存到文件中。

 

 

© 著作权归作者所有

一只小江
粉丝 102
博文 21
码字总数 51352
作品 0
杭州
程序员
私信 提问
加载中

评论(24)

itfanr
itfanr
http://www.sysnote.org/2015/11/25/ceph-osd-rw1/
itfanr
itfanr
http://www.sysnote.org/2015/11/25/ceph-osd-rw2/
梦深处
梦深处
您好,请问handle_op()将OSD的处理转换为PG的处理,这样做的目的是什么?理论上来说在OSD数据处理之前我就可以获得到相应的PG了,请指教?
消磨时间
消磨时间
我想问下ceph中怎么处理请求超时?
比如osd1发送一个请求给osd2,之后就等待osd2的响应,哪里设置的响应超时啊?
TOV
TOV
on_all_commit on_all_applied这两个回调函数是怎么触发的。 我调试堆栈发现是从finisher线程调用,但是还未找到如何触发它们
一只小江
一只小江 博主

引用来自“zhiyuan”的评论

博主您好,非常感谢楼主的分享,刚刚接触Ceph的RODOS不久,有几个问题想向您请教
请问on_all_commit表示所有的OSD都已经将日志写入底层存储
那么on_all_applied代表OSDs都处于什么状态呢?
另外当on_all_commit或者on_all_applied回调完成后,都会向Client返回请求,但是按照普通的理解,客户端只会收到一个请求,如果是这样的话,那么根据客户端请求的参数确定在哪个回调返回吗?
另外请帮忙解释一下onreadable, ondisk, onreadable_sync这三个状态都分别对应OSD集群的什么状态呢?
谢谢
这部分很多网上的介绍都有,可以搜一下看看,会介绍什么是commit 什么是applied。这些和osd的集群状态没什么直接的联系,一个是io完成的状态,一个是集群状态。
z
zhiyuan
博主您好,非常感谢楼主的分享,刚刚接触Ceph的RODOS不久,有几个问题想向您请教
请问on_all_commit表示所有的OSD都已经将日志写入底层存储
那么on_all_applied代表OSDs都处于什么状态呢?
另外当on_all_commit或者on_all_applied回调完成后,都会向Client返回请求,但是按照普通的理解,客户端只会收到一个请求,如果是这样的话,那么根据客户端请求的参数确定在哪个回调返回吗?
另外请帮忙解释一下onreadable, ondisk, onreadable_sync这三个状态都分别对应OSD集群的什么状态呢?
谢谢
漂泊的灯

引用来自“漂泊的灯”的评论

还有一个问题,对于librbd我们知道是通过client---->librados---->pool---->rbd---->pg---->osd,
kernel rbd的流程是怎样走的呢,它被集成在内核里面,不太清楚下面的具体流程。

引用来自“一只小江”的评论

kernel rbd 开始于rbd内核驱动模块的加载,由ceph的rbd map命令将新的rbd设备添加到系统中,rbd设备由内核rbd模块驱动。在ceph的rbd map过程中会把ceph的配置文件导入到内核中。新的rbd设备存在读写操作时,会根据ceph的配置文件生成对应的crush算法,计算pool rbd pg osd等信息(同librbd的道理一样)。然后内核中直接建立socket与目标osd进程通信传输数据。 想要实现kernel rbd调用librbd有点难度的,如果可以这样做那ceph早就应该实现了,不必要实现librbd和kernel rbd两套东西。kernel rbd内核模块是不能直接调用librbd的库。但是可以去做个demo尝试下,效果怎么样就不知道了。开辟一块共享内存用于数据在内核与用户态间的传递,用户空间运行一个cephrbd的服务。内核空间可以自己写一个rbd模块,该模块尽量简化,用于传递命令和数据,实现对io的转发操作,将io转发到用户空间,在用户空间的cephrbd服务中调用librbd实现io操作。 这个实现起来还是有一定难度的,由于涉及到内核模块的开发,需要考虑周全,容易造成系统抛出堆栈死机情况。

引用来自“漂泊的灯”的评论

非常感谢,我的大体思路差不多也是这样。我看了下内核的代码,其中还是有些疑惑。 1. librbd接口只要都是针对于image设计的,而kernel rbd的接口都是基于pg的(libceph) 2. libceph的很多接口都是extern外部的函数,但是不知道他是在哪里实现的,比如:ceph_copy_user_to_page_vector(在ceph的代码里面也没有找到)。 3. rbd map的代码在rbd.c里面貌似没有找到。

引用来自“一只小江”的评论

1. 其实用户librbd与kernelrbd都是一样,都需要一个被操作的对象image/rbd。用户空间的lirbd可以针对于image操作,kernel rbd的很多操作都被块设备取代了,所以libceph都是已经进入到rbd内部以后的操作,这与用户空间的librados库相似。 2. libceph是内核代码,虽然很多接口是extern标识,但是他是用了内核其他模块中的代码,所以这个代码还要在内核rbd代码中找,ceph_copy_user_to_page_vector 这个函数就在 linux-4.14/net/ceph/pagevec.c中。 3. rbd map 是用户空间程序在ceph的代码里,不再kernel rbd的代码里。用户程序编译出rbd命令,内核加载rbd 模块后,使用rbd map命令才会生效。rbd map 是一个由用户态程序到内核态程序扩展的过程。细看rbd map的代码 用户空间调用栈(全是ceph的代码) rbd map -> do_kernel_map() -> krbd_map() -> map_image() -> do_map( ) -> sysfs_write_rbd_add( ) -> sysfs_write_rbd( ) 最后函数中会操作目录文件 /sys/bus/rbd/add,这个文件是内核rbd模块导出的一个sysfs的接口,通过操作这个文件通知内核 开始创建一个rbd设备,开始进入到内核 rbd.c 模块中 static BUS_ATTR(add, S_IWUSR, NULL, rbd_add); 定义了add rbd的方法,然后会调用rbd_add()->do_rbd_add()..........开始内核之旅。直到添加一个块设备rbd。
感谢!
一只小江
一只小江 博主

引用来自“漂泊的灯”的评论

还有一个问题,对于librbd我们知道是通过client---->librados---->pool---->rbd---->pg---->osd,
kernel rbd的流程是怎样走的呢,它被集成在内核里面,不太清楚下面的具体流程。

引用来自“一只小江”的评论

kernel rbd 开始于rbd内核驱动模块的加载,由ceph的rbd map命令将新的rbd设备添加到系统中,rbd设备由内核rbd模块驱动。在ceph的rbd map过程中会把ceph的配置文件导入到内核中。新的rbd设备存在读写操作时,会根据ceph的配置文件生成对应的crush算法,计算pool rbd pg osd等信息(同librbd的道理一样)。然后内核中直接建立socket与目标osd进程通信传输数据。 想要实现kernel rbd调用librbd有点难度的,如果可以这样做那ceph早就应该实现了,不必要实现librbd和kernel rbd两套东西。kernel rbd内核模块是不能直接调用librbd的库。但是可以去做个demo尝试下,效果怎么样就不知道了。开辟一块共享内存用于数据在内核与用户态间的传递,用户空间运行一个cephrbd的服务。内核空间可以自己写一个rbd模块,该模块尽量简化,用于传递命令和数据,实现对io的转发操作,将io转发到用户空间,在用户空间的cephrbd服务中调用librbd实现io操作。 这个实现起来还是有一定难度的,由于涉及到内核模块的开发,需要考虑周全,容易造成系统抛出堆栈死机情况。

引用来自“漂泊的灯”的评论

非常感谢,我的大体思路差不多也是这样。我看了下内核的代码,其中还是有些疑惑。 1. librbd接口只要都是针对于image设计的,而kernel rbd的接口都是基于pg的(libceph) 2. libceph的很多接口都是extern外部的函数,但是不知道他是在哪里实现的,比如:ceph_copy_user_to_page_vector(在ceph的代码里面也没有找到)。 3. rbd map的代码在rbd.c里面貌似没有找到。
1. 其实用户librbd与kernelrbd都是一样,都需要一个被操作的对象image/rbd。用户空间的lirbd可以针对于image操作,kernel rbd的很多操作都被块设备取代了,所以libceph都是已经进入到rbd内部以后的操作,这与用户空间的librados库相似。 2. libceph是内核代码,虽然很多接口是extern标识,但是他是用了内核其他模块中的代码,所以这个代码还要在内核rbd代码中找,ceph_copy_user_to_page_vector 这个函数就在 linux-4.14/net/ceph/pagevec.c中。 3. rbd map 是用户空间程序在ceph的代码里,不再kernel rbd的代码里。用户程序编译出rbd命令,内核加载rbd 模块后,使用rbd map命令才会生效。rbd map 是一个由用户态程序到内核态程序扩展的过程。细看rbd map的代码 用户空间调用栈(全是ceph的代码) rbd map -> do_kernel_map() -> krbd_map() -> map_image() -> do_map( ) -> sysfs_write_rbd_add( ) -> sysfs_write_rbd( ) 最后函数中会操作目录文件 /sys/bus/rbd/add,这个文件是内核rbd模块导出的一个sysfs的接口,通过操作这个文件通知内核 开始创建一个rbd设备,开始进入到内核 rbd.c 模块中 static BUS_ATTR(add, S_IWUSR, NULL, rbd_add); 定义了add rbd的方法,然后会调用rbd_add()->do_rbd_add()..........开始内核之旅。直到添加一个块设备rbd。
漂泊的灯

引用来自“漂泊的灯”的评论

还有一个问题,对于librbd我们知道是通过client---->librados---->pool---->rbd---->pg---->osd,
kernel rbd的流程是怎样走的呢,它被集成在内核里面,不太清楚下面的具体流程。

引用来自“一只小江”的评论

kernel rbd 开始于rbd内核驱动模块的加载,由ceph的rbd map命令将新的rbd设备添加到系统中,rbd设备由内核rbd模块驱动。在ceph的rbd map过程中会把ceph的配置文件导入到内核中。新的rbd设备存在读写操作时,会根据ceph的配置文件生成对应的crush算法,计算pool rbd pg osd等信息(同librbd的道理一样)。然后内核中直接建立socket与目标osd进程通信传输数据。 想要实现kernel rbd调用librbd有点难度的,如果可以这样做那ceph早就应该实现了,不必要实现librbd和kernel rbd两套东西。kernel rbd内核模块是不能直接调用librbd的库。但是可以去做个demo尝试下,效果怎么样就不知道了。开辟一块共享内存用于数据在内核与用户态间的传递,用户空间运行一个cephrbd的服务。内核空间可以自己写一个rbd模块,该模块尽量简化,用于传递命令和数据,实现对io的转发操作,将io转发到用户空间,在用户空间的cephrbd服务中调用librbd实现io操作。 这个实现起来还是有一定难度的,由于涉及到内核模块的开发,需要考虑周全,容易造成系统抛出堆栈死机情况。
非常感谢,我的大体思路差不多也是这样。我看了下内核的代码,其中还是有些疑惑。 1. librbd接口只要都是针对于image设计的,而kernel rbd的接口都是基于pg的(libceph) 2. libceph的很多接口都是extern外部的函数,但是不知道他是在哪里实现的,比如:ceph_copy_user_to_page_vector(在ceph的代码里面也没有找到)。 3. rbd map的代码在rbd.c里面貌似没有找到。
ceph的数据存储之路(1) ---rbd设备介绍

由这几个问题开始思考。。。 问题0,数据的存储设备? 数据的存储有3种形式,1种是直接以二进制数据的形式存储在裸设备(包括块设备)上,另外一种是以文件的形式经过文件系统管理进行存储。...

一只小江
2015/11/17
3.6K
1
ceph的数据存储之路(4) ----- rbd client 端的数据请求处理

2016-11-01更新 start:-------------------------------------------------------------------------------------- 最近比较多的人私下问我,改了ceph的源码,重新编译了,但是在使用本节提...

一只小江
2015/11/19
8.1K
23
从传统运维到云运维演进历程之软件定义存储(三)下

上回书讲到了运维小哥的调优方法论(上),对于Ceph运维人员来说最头痛的莫过于两件事:一、Ceph调优;二、Ceph运维。调优是件非常头疼的事情,下面来看看运维小哥是如何调优的。 关卡二:部...

Devin
2016/10/11
0
0
从传统运维到云运维演进历程之软件定义存储(六)完结

回到最初的Ceph运维工程师的问题,本系列讲述的是传统运维向新一代云运维转型之软件定义存储部分的转型,运维是企业业务系统从规划、设计、实施、交付到运维的最后一个步骤,也是重要的步骤。...

Devin
2016/12/20
0
0
“Ceph浅析”系列之七——关于Ceph的若干想法

本篇文章的内容,主要是笔者在调研分析Ceph过程中产生的一些思考。因为其中的内容比较自由发散,且大多是笔者的个人见解,故此另启一文进行讨论。 7.1 关于Ceph的性能 目前为止,本系列的文章...

红薯
2014/04/01
1K
2

没有更多内容

加载失败,请刷新页面

加载更多

总结:TCP/IP协议

一、介绍 TCP协议属于OSI七层模型中的传输层协议,提供处于网络连接中的两台计算机之间的数据 传输。   在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议...

浮躁的码农
16分钟前
2
0
一言不合就删库跑路?万名贡献者和阿里巴巴开源的二三事

9 月 27 日云栖大会,阿里巴巴宣布贾扬清担任开源技术委员会负责人。 有人问:开源是为了什么? 从个人视角看,可以证明自己的专业能力,获得行业认可; 从企业视角看,可以建立技术影响力,...

大涛学弟
27分钟前
3
0
JAVA编程注意事项(性能篇)

1. 尽量在合适的场合使用单例 使用单例可以缩短加载的时间,提高加载的效率,单例主要适用于以下三个方面: 第一,控制资源的使用,通过线程同步来控制资源的并发访问; 第二,控制实例的产生...

你好夜故事
28分钟前
3
0
List 前端 AngularJS JS 对IP排序

数据格式 $scope.dataList=[ {"ip":"192.168.10.10", "port":"8080",...}, { "ip":"192.168.10.12", "port":"8080",... } ,.....] 调用 $scope.ipSortForward($scope.dataList,"ip") 核心代码......

最菜最菜之小菜鸟
28分钟前
3
0
浅析Cassandra LeveledCompactionStrategy

前言 Cassandra是基于LSM架构的分布式数据库。LSM中有一个很重要的过程,就是压缩(Compaction)。默认的压缩策略是SizeTieredCompactionStrategy,今天主要说一下另一种压缩策略LeveledComp...

阿里云官方博客
33分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部