共计 6013 个字符,预计需要花费 16 分钟才能阅读完成。
最近在做 OpenStack Cinder driver 的性能调试, 之前一直是通过在 driver 里面加入 decorator,完成 driver 各个接口的执行时间的统计。
其实在 openstack,已经在孵化一个叫 osprofiler 的 project,然后这个可以通过与 OpenStack Ceilometer 的集成,可以轻松完成性能数据的统计,大幅的节省性能调优的时间.
- osprofiler 原理:
通过在 OpenStack 不同 Component 之间使用 osprofiler 的 trace,记录所有的 wsgi,rpc,driver 各个接口的开始和结束时间,然后通过 rpc message 把记录到的数据发送到 Ceilometer 数据库进行存储。
这样用户可以在执行完 OpenStack 的操作后,通过 osprofiler 的 CLI 接口,以 html 或者 JSON 的格式可视化的显示出各个接口的执行顺序和时间,从而发现一个 call stack 的瓶颈。
更多关于 osprofier 可以参见 https://github.com/stackforge/osprofiler
[NOTE]: 有网友反映和本人自己的实验,在最新的 master branch 上,不能正确产生正确的 osprofiler 数据,error 如下:
[待增加]
解决方案是使用 kilo 版本:
cd ~/devstack | |
# 保存当前的 change | |
git stash | |
git checkout stable/kilo | |
# 重新应用 change | |
git stash pop | |
# 其他配置保持不变 | |
# 让后在./stack.sh | |
./stack.sh# 升级 Python-cinderclient, 安装 python-ceilometerclientsudo pip install python-cinderclient --upgradesudo pip install python-ceilometerclient | |
- 基本的使用:
from osprofiler import profiler | |
# 使用前,一定要 init,否则不会用任何的数据记录 | |
profiler.init("SECRET_HMAC_KEY", base_id='sadfsdafasdfasdfas', parent_id='dsafafasdfsadf') | |
def some_func(): | |
profiler.start("point_name", {"any_key": "with_any_value"}) | |
# your code | |
print "I am between some_func" | |
profiler.stop({"any_info_about_point": "in_this_dict"}) | |
info={"any_info_about_point": "in_this_dict"}, | |
hide_args=False) | |
def some_func2(*args, **kwargs): | |
# If you need to hide args in profile info, put hide_args=True | |
print "Hello, osprofiler" | |
pass | |
def some_func3(): | |
with profiler.Trace("point_name", | |
info={"any_key": "with_any_value"}): | |
# some code here | |
pass | |
trace_private=False) | |
class TracedClass(object): | |
def traced_method(self): | |
print "Trace me" | |
pass | |
def _traced_only_if_trace_private_true(self): | |
pass | |
# 把所有的记录写入到 json 文件里面 | |
def send_info_to_file_collector(info, context=None): | |
with open("traces", "a") as f: | |
f.write(json.dumps(info)) | |
notifier.set(send_info_to_file_collector) | |
# 下面的函数调用都会被一一记录 | |
some_func() | |
some_func2(test='asdfasdf', adf=313) | |
trace = TracedClass() | |
trace.traced_method() |
然后,你在当前目录的 traces 文件问发现很多的 log,有个问题数据的可读性比较差,那么 OpenStack 是怎么解决的呢?
答案是配合使用 Ceilometer. 关于 Ceilometer,参考它的框架,可以帮助理解 http://docs.openstack.org/developer/ceilometer/architecture.html#high-level-architecture
下面以 lvm 的 cinder driver 为例,说明如何配置 Cinder,osprofiler 以及 Ceilometer 的集成,,
- 首先,要 setup devstack,下面是 devstack 的 local.conf 的配置:(如果你是首次使用 devstack,请移步 http://www.linuxidc.com/Linux/2016-01/127509.htm)
(注意,我 enable 了 Ceilometer 和 Neutron 的所有组件,在使用这个文件时,要把 HOST_IP, SERVICE_HOST 改为本机的 IP
[[local|localrc]] | |
HOST_IP=192.168.14.128 | |
SERVICE_HOST=192.168.14.128 | |
ADMIN_PASSWORD=welcome | |
DATABASE_PASSWORD=$ADMIN_PASSWORD | |
RABBIT_PASSWORD=$ADMIN_PASSWORD | |
SERVICE_PASSWORD=$ADMIN_PASSWORD | |
SERVICE_TOKEN=$ADMIN_PASSWORD | |
DEST=/opt/stack | |
LOGFILE=$DEST/logs/stack.sh.log | |
SCREEN_LOGDIR=$DEST/logs/screen | |
OFFLINE=False | |
RECLONE=False | |
LOG_COLOR=False | |
disable_service horizon | |
enable_service q-svc | |
enable_service q-agt | |
enable_service q-dhcp | |
enable_service q-l3 | |
enable_service q-meta | |
enable_service neutron | |
# Enable the ceilometer metering services | |
enable_service ceilometer-acompute ceilometer-acentral ceilometer-anotification ceilometer-collector | |
# Enable the ceilometer alarming services | |
enable_service ceilometer-alarm-evaluator,ceilometer-alarm-notifier | |
# Enable the ceilometer api services | |
enable_service ceilometer-api# 这个 profiler 一定要加,是 cinder 的性能信息记录到 Ceilometer 的关键 | |
CEILOMETER_NOTIFICATION_TOPICS=notifications,profiler | |
disable_service n-net | |
disable_service tempest | |
disable_service h-eng,h-api,h-api-cfn,h-api-cw | |
PHYSICAL_NETWORK=physnet1 | |
FIXED_RANGE=192.168.106.0/24 | |
FIXED_NETWORK_SIZE=32 | |
NETWORK_GATEWAY=192.168.106.1 | |
[[post-config|$CINDER_CONF]] | |
[profiler] | |
profiler_enabled = True | |
trace_sqlalchemy = False | |
[[post-config|/$Q_PLUGIN_CONF_FILE]] | |
[ml2] | |
tenant_network_types = vlan | |
[ml2_type_vlan] | |
network_vlan_ranges = physnet1:100:110 | |
[ovs] | |
bridge_mappings = physnet1:br-eth1 | |
enable_tunneling = False |
然后就是执行 ./stack.sh
- 产生与收集 Cinder 操作的性能数据:
peter@Ubuntu:~/devstack$ cinder --profile SECRET_KEY create --name peter 1 | |
+---------------------------------------+--------------------------------------+ | |
| Property | Value | | |
+---------------------------------------+--------------------------------------+ | |
| attachments | [] | | |
| availability_zone | nova | | |
| bootable | false | | |
| consistencygroup_id | None | | |
| created_at | 2015-04-04T14:58:51.000000 | | |
| description | None | | |
| encrypted | False | | |
| id | 28857983-3240-445d-a60b-3b91295c31e8 | | |
| metadata | {} | | |
| multiattach | False | | |
| name | peter | | |
| os-vol-host-attr:host | None | | |
| os-vol-mig-status-attr:migstat | None | | |
| os-vol-mig-status-attr:name_id | None | | |
| os-vol-tenant-attr:tenant_id | ade7584debc54964b4fef737e56e062d | | |
| os-volume-replication:driver_data | None | | |
| os-volume-replication:extended_status | None | | |
| replication_status | disabled | | |
| size | 1 | | |
| snapshot_id | None | | |
| source_volid | None | | |
| status | creating | | |
| user_id | 56aac792735046dea02e12e85e0d1a03 | | |
| volume_type | lvmdriver-1 | | |
+---------------------------------------+--------------------------------------+ | |
Trace ID: aa4903cc-fd0c-42ef-96f1-bd1c5a1740f1 | |
To display trace use next command: | |
osprofiler trace show --html aa4903cc-fd0c-42ef-96f1-bd1c5a1740f1 |
- 导出性能测试的数据为 HTML 格式
osprofiler trace show --html aa4903cc-fd0c-42ef-96f1-bd1c5a1740f1 --out test.html
html 内容如下(需要 FQ,这个页面需要访问 google.com ^_^)
- 查看各个接口的执行时间,下图给出了每个被统计的接口在不同的 service 之间的执行时间
- 查看接口的参数,可以点击函数,查看具体的参数
上面的 view 可以很轻松的实现对 openstack 各个接口调用执行时间的统计,可视化的显示了特定操作的性能瓶颈在哪里。
- Cinder driver 的各个接口的性能统计:
上面的工作,还有一个问题没有解决,如果你的 driver 其实有多个层级的 class(如 driver.create_volume->AnotherClass.def1->AnotherClass.def2->AnotherClass.defn),那么我只知道入口函数 driver.create_volume 的执行时间,并不知道在 AnotherClass 内部各个接口的执行时间(def1 多少时间,def2 多少时间。这个就要稍微改下 lvm driver 的代码了,可以为 lvm driver 的所有 class 加上如下的 decorator:
trace_private=True) | |
class AnotherClass(object): | |
def def1: | |
pass | |
def def2: | |
pass |
参考文章及深入阅读:
- osprofiler README
- Integrate OSprofiler and Cinder
- osprofiler specs
- OpenStack Ceilometer
- Integrate OSprofiler and Nova
下面是小编为你精选的 Openstack 相关知识,看看是否有你喜欢的:
在 Ubuntu 12.10 上安装部署 Openstack http://www.linuxidc.com/Linux/2013-08/88184.htm
Ubuntu 12.04 OpenStack Swift 单节点部署手册 http://www.linuxidc.com/Linux/2013-08/88182.htm
OpenStack 云计算快速入门教程 http://www.linuxidc.com/Linux/2013-08/88186.htm
企业部署 OpenStack:该做与不该做的事 http://www.linuxidc.com/Linux/2013-09/90428.htm
CentOS 6.5 x64bit 快速安装 OpenStack http://www.linuxidc.com/Linux/2014-06/103775.htm
本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-01/127508.htm
