看懂日志系列,结合代码,针对rgw的上传op进行了日志的解读
写在前面
松鼠哥的ceph专业课程上线啦!
面向新手同学,从0实战,全面入门ceph安装部署与运维,有需要的同学赶紧扫码订购吧:
此前博客有针对osd日志解读的文章,本篇继续延续该系列,解读ceph rgw的日志,选取上传对象的日志进行分析
从上传说起
对象存储网关rgw是上传对象到ceph的入口,其功能、性能直接面向用户,对rgw深入理解,读懂日志,有助于我们排查、定位问题及调优,并在此基础上做可能的二次开发,本次对rgw日志的解读仍然采用20/20的日志,上传单个文件和分片文件进行流程解读,版本为mimic 13.2.5
rgw日志解读
选取rgw 20/20级别的日志,上传单个文件和分片文件进行流程解读,版本为mimic 13.2.5
配置情况
1 | 上传客户端使用s3cmd,其默认分片大小为15M |
不分片的情况
首先,随便选择一个较小的文件,上传到集群的一个bucket中
1 | [store@server227 build]$ s3cmd put radosgw.8000.log s3://cpp-bucket1/test.file |
然后,将得到的日志进行解读
1 | 2019-05-31 16:36:27.857 7fdc91735700 20 CONTENT_LENGTH=82695 |
这是一个http请求进来后的第一个处理流程,主要进行解析这个http头的信息,主要关注的地方有三个
第一个是CONTENT_LENGTH
,可以看到这个值就是我们上传的文件的大小
第二个是REQUEST_METHOD
,这个请求是PUT,表示上传数据
第三个是REQUEST_URI
,显示这个请求的bucket以及key,也就是请求的资源
1 | 2019-05-31 16:36:27.857 7fdc91735700 1 ====== starting new request req=0x7fdc9172ec80 ===== |
这一段显示这个http请求被正式处理,主要操作是进行http格式化,检查各个字段,进行基本的字段认证,这里主要关注的地方有两个
首先是op=21RGWPutObj_ObjStore_S3
,这个字段表明了这个请求的op类型,就是上传对象
其次是x-amz-开头的三个字段,它是对象的拓展属性,将会被存储在rados的对象的属性字段
到这里为止,可以认为第一阶段,s3请求的初步解析完成了,注意到,整个过程只用了1ms
继续往下
1 | 2019-05-31 16:36:27.858 7fdc91735700 15 server signature=9ISu+ty4SOQZ+9xcSkpSe5nRpdM= |
到这里,可以称为第二阶段,主要进行行为的鉴权,主要是
- 对比op与server的signature
- 判断用户是否有权限操作对应的资源
- 判断这个op是否合法
- 确认权限掩码及权限参数
当一个s3写入请求被返回403或者400时,多半是这个地方校验失败导致,具体要看日志的说法,这个阶段处理时间也是在1ms
内
继续往下
1 | 2019-05-31 16:36:27.858 7fdc91735700 2 req 7:0.000999971s:s3:PUT /cpp-bucket1/test.file:put_obj:executing |
上述过程主要执行的函数在src/rgw/rgw_op.cc
的RGWPutObj::execute
函数中,进行的动作在日志中没有太多的体现,检查代码能发现不少东西
在executing
日志打印之后,handler进入RGWPutObj::execute
,进行一些配置的设置和检查,例如md5计算配置、etage、chunk配置等,然后进入数据的读取
1 | //开始循环从缓冲区读取数据,读到数据后会立即写入osd |
可以看到,当日志中打印NOTICE: call to do_aws4_auth_completion
即表示数据读取完成
这里面用到参数rgw_max_chunk_size
,它是从配置中读取的,默认是4M,它表示每次从缓冲区读取多少数据,开头我们将其设置为8M,但是注意,这个数据大小不是直接下发到osd的数据大小,实际上读出这块数据之后,如果大于4M,则会以4M为一块,下发到osd中,这里上传的数据不足4M,所以直接就读出来下发到osd了,另外,这些读出的数据,会进行md5的计算,确保完整性
至此,上传对象的数据部分就上传完成了,这个过程耗时10ms
,从这里也可以看出,针对大文件,尤其是百M以上文件写入为主的场景,调大这个值有助于提高性能
1 | 2019-05-31 16:36:27.868 7fdc91735700 20 get_obj_state: rctx=0x7fdc9172e440 obj=cpp-bucket1:test.file state=0x5619dcf915a0 s->prefetch_data=0 |
上一段看到,数据部分读取完成,于是接下来进行了元数据的更新,首先是确认对象的状态,get_obj_state
,然后操作default.rgw.meta
中的信息,更新相关内容,最后我们看到会更新index
,这个地方比较关键,如果是海量文件存储,更新index中的内容将非常耗时
上述属于第二阶段,完成数据的读取和元数据信息的更新,总共耗时21ms
1 | 2019-05-31 16:36:27.879 7fdc91735700 2 req 7:0.0219994s:s3:PUT /cpp-bucket1/test.file:put_obj:completing |
最后,handler将处理结果封装成http响应,返回给客户端,是每个op的最后一个阶段
这个op总耗时是26ms
,其中第二阶段数据上传和元数据更新花费时间为21ms
,占比80%
总结
上述可以看到,rgw处理普通的上传op过程中,会进行三个阶段的处理,首先是进行op的鉴权,然后是数据的接收和分发,更新元数据,最后是返回HTTP请求,从中我们也可以看到第二阶段的耗时最大,从中可以定位到性能优化点,例如减小网络延时、使用巨帧一次性传输更多的数据、加大一次从缓冲区读取的参数值,甚至是rados的块大小。在下篇,我们会针对分块上传进行分析,敬请期待
- 本文作者: 奋斗的松鼠
- 本文链接: http://www.strugglesquirrel.com/2019/07/07/看懂ceph日志系列之rgw上传op处理流程-上/
- 版权声明: 本博客所有文章除特别声明外,创作版权均为作者个人所有,未经允许禁止转载!