本节介绍如何使用 rgw tracepoints 跟踪 rgw 数据传送、bi更新和头对象写的时间开销。
1. 打过patch后,获取 trace数据
操作和 [1] 中过程一样。不一样的处理如下:
- apply patch [2]
- 编译打开 lttng 支持(同[1])
- ceph.conf 中配置项打开
rgw rados tracing = true
rgw op tracing = true
2. 处理获取到的数据
上脚本
#!/usr/bin/env python
# -*- coding: utf-8 -*
# vi:set tw=0 ts=4 sw=4 nowrap fdm=indent
# Yang Honggang <rtlinux@163.com>
import pdb
import json
import sys
from babeltrace import *
# all events
g_events = set()
g_summary = {}
def update_summary(evt_name, cost):
g_events.add(evt_name)
if evt_name not in g_summary:
g_summary[evt_name] = {
'max': cost,
'min': cost,
'sum': cost,
'count': 1
}
else:
e = g_summary[evt_name]
if e['max'] < cost:
e['max'] = cost
if cost < e['min']:
e['min'] = cost
e['sum'] += cost
e['count'] += 1
def update():
for k, v in g_summary.items():
v['avg'] = float(v['sum']) // v['count']
v['avg'] /= float(1000000000)
v['min'] /= float(1000000000)
v['max'] /= float(1000000000)
v['sum'] /= float(1000000000)
if __name__ == '__main__':
traces = TraceCollection()
ret = traces.add_trace(sys.argv[1], "ctf")
event_type = 'all'
if len(sys.argv) == 3:
event_type = str(sys.argv[2])
events_enter = {}
events_enter_set = set()
for event in traces.events:
# filter
if event_type != 'all' and event_type not in event.name:
continue
if event.name == 'rgw_op:before_data_receive':
op_tag = event.name + str(event['req_id'])
# print ('enqueue %s' % op_tag)
if op_tag in events_enter_set:
print ('reset %s' % op_tag)
events_enter_set.add(op_tag)
events_enter[op_tag] = {
'ts': event.timestamp,
}
continue
if event.name == 'rgw_op:after_data_receive':
op_tag = 'rgw_op:before_data_receive' + str(event['req_id'])
# print ('dequeue %s' % op_tag)
try:
e = events_enter[op_tag]
cost = event.timestamp - e['ts']
update_summary('rgw_op:data_receive', cost)
del events_enter[op_tag]
events_enter_set.remove(op_tag)
print ('%s %d' % ('rgw_op:data_receive', cost))
except KeyError:
print ('drop %s' % str(event))
continue
if event.name.startswith('rgw_') and event.name.endswith('_enter'):
op_tag = event.name + str(event['req_id'])
# print ('enqueue %s' % op_tag)
assert(op_tag not in events_enter_set), ("dump events_enter_set: %s" % str(pdb.set_trace()))
if op_tag in events_enter_set:
print ('reset %s' % op_tag)
events_enter_set.add(op_tag)
events_enter[op_tag] = {
'ts': event.timestamp,
}
continue
if event.name.startswith('rgw_') and event.name.endswith('_exit'):
op_tag = event.name[:-4] # get rid of tail 'exit'
op_tag += 'enter' + str(event['req_id'])
# print ('dequeue %s' % op_tag)
try:
e = events_enter[op_tag]
cost = event.timestamp - e['ts']
update_summary(event.name[:-5], cost)
del events_enter[op_tag]
events_enter_set.remove(op_tag)
print ('%s %d' % (event.name[:-5], cost))
except KeyError:
print ('drop %s' % str(event))
continue
# update avg
update()
print (json.dumps(g_summary, indent=4))