文档章节

Ceph RGW的usage数据从何而来?

linuxcs
 linuxcs
发布于 2016/08/24 17:05
字数 1219
阅读 49
收藏 0

uRGW 的Usage信息是如何获取到的? 获取RGW的Usage信息,主要是来自于rgw_admin.cc中的函数:RGWUsage::show()。 这个函数定义在rgw/rgw_usage.h,实现于rgw/rgw_usage.cc 在文件rgw/rgw_usage.cc中可以看到函数的实现。 RGWUsage::show() 输入参数: RGWRados ×store (RGWRados类定义在rgw/rgw_rados.h中,) string& uid (用户名) uint64_t start_epoch(开始的时间) uint64_t end_epoch (结束的时间) ......

从store结构体中调用函数read_usage() 转到rgw/rgw_rados.h中,可以看到read_usage()的声明 在rgw/rgw_rados.cc中可以查看到read_usage()函数的实现。 可以看到read_usage()函数调用的是cls_obj_usage_log_read()。 cls_obj_usage_log_read()调用的是cls_rgw_usage_log_read() 在cls/rgw/cls_rgw_client.cc的249行:cls_rgw_usage_log_read()这个函数里: bufferlist in, out ::encode(call, in) 对bufferlist in进行编码处理,在函数exec中执行。 map<rgw_user_bucket, rgw_usage_log_entry> usage; void encode(bufferlist& bl) { ::encode()//表示这是一个全局函数。用于和局部或者成员函数来区分。 } iter是一个bufferlist迭代器类型。

io_ctx.exec是一个插件的动态加载函数,加载的函数是rgw_user_usage_log_read(),参数分别是in和out。 执行rgw_user_uage_log_read()函数实际上读取的真正的用户使用信息,将结果返回到out这个bufferlist中去。 然后从out中解码用户使用信息,将结果保存到result。 最终,result.usage被保存到了usage中。(由于usage是一个map<rgw_user_bucket, rgw_usage_log_entry>类型的引用,所以,此时就相当于直接修改了usage变量。) 也就是将结果保存到了usage中。

以上是各个函数的调用关系 当函数cls_rgw_usage_log_read()「rgw/cls_rgw_client.cc:249line」返回后,

返回到了调用它的函数RGWRados::cls_obj_usage_log_read()「rgw/rgw_rados.cc:6021line」 此时,已经将参数usage进行了设置。

然后,函数RGWRados::cls_obj_usage_log_read()继续返回,返回到调用它的函数:RGWRados::read_usage()函数。 在RGWRados::read_usage()这个函数中,会在循环条件之下,反复调用cls_obj_usage_log_read()这个函数。

其中,作为存储usage的相关数据结构就是map<rgw_user_bucket, rgw_usage_log_entry> 这是一个复合的数据结构, rgw_usage_log_entry

在io_ctx.exec中调用rgw_user_usage_log_read(),「这是一个封装在插件中的函数」 前一行的::encode(),是将call这个数据结构执行序列化操作,并将序列化操作放到in这个bufferlist中。 假设现在已经将call这个数据结构序列化到了in这个bufferlist中了。进入到rgw_user_usage_log_read()「位于cls/rgw/cls_rgw.cc:1199line」 这个函数的参数正好是bufferlist类型的in和out。 「可以看出,之前的call(rgw/cls_rgw_client.cc:257line)和这里的op是同一个数据类型。 1213 line的ret_info和rgw/cls_rgw_client.cc:269line的result也是同样的数据类型。」

在rgw_user_usage_log_read()函数中,首先对参数in进行反序列化操作,「即就是decode(op, in_iter)」.

反序列化后的结果保存在了op「类型rgw_cls_usage_log_read_op,和之前的call是一个类型的」 随后,使用一个map集合类型的指针变量usage指向了ret_info.usage「ret_info类型是rgw_cls_usage_log_read_ret,和result一致」 max_entries设置了最多能记录多少项。

函数usage_iterate_range(...,(void *)usage)最后是一个指针类型的参数,从后面的代码可以肯定,此函数修改了usage指示的内存地址内容。 而usage指示的内存地址如前所述,恰好是ret_info.usage指示的地址,所以usage_iterate_range()修改的是ret_info.usage的内容, 随后,下一行的encode执行序列化操作,将ret_info内容序列化到out中去。「这里也是间接的修改了out这个bufferlist内存区。」 最终,out指示的bufferlist内存区就存放了user_usage的内容。

现在,唯一还不明了的就是usage_iterate_range()这个函数了。 此函数位于cls/rgw/cls_rgw.cc:1099line 原型:static int usage_iterate_range(cls_method_context_t hctx, uint64_t start, uint64_t end, string& user, string& key_iter, uint32_t max_entries, bool *truncated, int (*cb)(cls_method_context_t, const string&, rgw_usage_log_entry&, void *), void *param)

再来看看位于1199行是如何调用int usage_iterate_range() 参数列表中依次是:hctx,开始的周期,结束周期,所有者,iter(?),最大记录项数量,是否分段,函数指针指向 usage_log_read_cb(), usage指针,指向了ret_info.usage。 即:hctx, op.start_epoch, op.end_epoch, op.owner, iter, max_entries, &ret_info.truncated, usage_log_read_cb, (void )usage /*******************************************************

****************************************************************************/

usage_record_prefix_by_time() usage_record_prefix_by_user() 这两个函数都是相当于在key这个字符串前面添加一些前缀比如时间或者user而已。

关键是cb指针所指向的函数。即就是:usage_log_read_cb() usage_log_read_cb的函数原型是(1189行): static int usage_log_read_cb(cls_method_context_t hctx, const string& key, rgw_usage_log_entry& entry, void *param) 这是一个静态函数。 在函数中usage_log_read_cb() 中,初始化了一个对象ub(entry.owner, entry.bucket) 但是,目前还有一个疑问,所取得的数据到底是从哪里获取的?

usage得到的那些信息,最初的来源就是从函数cls_cxx_map_get_vals() 「./objclass/class_api.cc」 「反正在cls_cxx_map_get_vals()中执行了一些乱七八糟的操作」就把值交给了keys,keys解码,将usage数据放到了

usage的原始数据从何而来,也就是记录的数据又是从哪里得到的? 参见rgw/rgw_log.cc:167,函数log_usage()

© 著作权归作者所有

linuxcs
粉丝 1
博文 4
码字总数 3031
作品 0
绵阳
私信 提问
RGW Usage类解析

一、概述。 RGW Usage类实现了RGW的流量统计功能,其中包括发送/接收的字节数、执行操作的个数以及成功之行操作的个数。Usage类统计的这些内容对于一般的流量统计来说已经够用了。 二、核心...

linuxhunter
2016/04/19
265
0
Ceph 0.85 发布,分布式文件存储系统

Ceph 0.85 发布了,值得关注的改进有: ceph-disk: do not inadvertantly create directories (Owne Synge) ceph-disk: fix dmcrypt support (Sage Weil) ceph-disk: linter cleanup, loggin......

oschina
2014/09/09
1K
0
Ceph RGW中各Pool的作用

Ceph RGW中各Pool的作用 1.引言 在使用Ceph的radosgw服务时,会通过create pool命令创建一系列的pool,服务于radosgw.我想在本文中分析出各个pool的作用。 2.pool信息罗列 上文罗列了所有默认...

西昆仑
2016/06/15
1K
0
Infernalis版本radosgw搭建配置

1.安装apache。 #apt-get install apache2 libapache2-mod-fastcgi 2.配置apache。 在apache配置文件中添加服务器名称,即:在/etc/apache2/apache2.conf文件添加如下内容: ServerName {fq...

linuxhunter
2016/04/06
141
0
利用bucket localtion实现rgw集群扩容

扩容思路:ceph集群容量不足的时候,新加的OSD组成新的pool,制定新的rule规则,新建的bucket都存放在这些新加入的pool里面,注意扩容仅限于新加的bucket,已有的bucket扩容不适用。 1.新建p...

秦牧羊
2016/07/07
503
1

没有更多内容

加载失败,请刷新页面

加载更多

关于AsyncTask的onPostExcute方法是否会在Activity重建过程中调用的问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/XG1057415595/article/details/86774575 假设下面一种情况...

shzwork
今天
6
0
object 类中有哪些方法?

getClass(): 获取运行时类的对象 equals():判断其他对象是否与此对象相等 hashcode():返回该对象的哈希码值 toString():返回该对象的字符串表示 clone(): 创建并返此对象的一个副本 wait...

happywe
今天
6
0
Docker容器实战(七) - 容器中进程视野下的文件系统

前两文中,讲了Linux容器最基础的两种技术 Namespace 作用是“隔离”,它让应用进程只能看到该Namespace内的“世界” Cgroups 作用是“限制”,它给这个“世界”围上了一圈看不见的墙 这么一...

JavaEdge
今天
8
0
文件访问和共享的方法介绍

在上一篇文章中,你了解到文件有三个不同的权限集。拥有该文件的用户有一个集合,拥有该文件的组的成员有一个集合,然后最终一个集合适用于其他所有人。在长列表(ls -l)中这些权限使用符号...

老孟的Linux私房菜
今天
7
0
面试套路题目

作者:抱紧超越小姐姐 链接:https://www.nowcoder.com/discuss/309292?type=3 来源:牛客网 面试时候的潜台词 抱紧超越小姐姐 编辑于 2019-10-15 16:14:56APP内打开赞 3 | 收藏 4 | 回复24 ...

MtrS
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部