前面说了region,az,aggregate,专门把对cell的积累做一节,当openstack部署成为公有云或者规模庞大的私有云时,还是存在性能瓶颈,我们能想到的:
1. keystone,使用uuid而非PKI时,keystone感觉立刻就会成为瓶颈,实际生产环镜肯定是配PKI的,当然了不只是openstack,很多大型网站,高并发时authorization
都是问题;
2. database, 即便是配成分布式数据库,作为IO的关卡,数据库操作必然会拖累memory操作;
3. MQ,据说使用ZeroMQ比RabbitMQ快上十倍,不过 MQ仍然是瓶颈所在,想想队列,缓存,持久化,网络操作,成为瓶颈也很正常。
keystone的问题,KPI可以解决一部分,也不在cell的范围之类,但是2和3是cell的初衷,每个cell有自己的databse和MQ(很遗憾,没有机会实际搭建带cell的环境),
然而通过分析源码,可以理解。
默认的是没有cell功能的,要使用cell,要在/etc/nova/nova.conf中[cells]配置,但配置文件中的配置有限,包括:
driver,manager,scheduler等,
此处driver为rpc的driver,有了cell之后, RPC 分为cell之间的通讯,cell内部的通讯,
manager是接到message的响应manager,scheduler则是manager中响应时可能用到的scheduler,很熟悉的套路。
看了前一节mark 的link还不够直观,trace into code,创建一个instance并且CONF.celss.enable为True时:
1, self.compute_api.create, self.compute_api= class_name = _get_compute_api_class_name()
cell_type = nova.cells.opts.get_cell_type() #cell disable时,compute.API()为nova.compute.api.API
return CELL_TYPE_TO_CLS_NAME[cell_type]
接收到nova-api请求的节点的cell type被配置为api,其他的cell配置为compute,这里需要指出的是,cell中配置nova-*的service是指除了
nova-api以外的其他service,一般地,parent cell配置cell type为api,child cell 配置cell type为compute,每个cell需要启动nova-cell服务。
BTW:需要通过nova-manage create cell,create时需要执行MQ的url和用户名,密码,cell类型为parent还是child等,写入数据库。
2,nova-api收到请求的cell type为api,对应的self.compute_api为“'api': 'nova.compute.cells_api.ComputeCellsAPI',”,继承自nova.compute.api.py中的API,
注意其__init__:
def __init__(self, *args, **kwargs):
super(ComputeCellsAPI, self).__init__(*args, **kwargs)
self.cells_rpcapi = cells_rpcapi.CellsAPI()
# Avoid casts/calls directly to compute
self.compute_rpcapi = ComputeRPCAPIRedirect(self.cells_rpcapi)
# Redirect conductor build_instances to cells
self._compute_task_api = ConductorTaskRPCAPIRedirect(self.cells_rpcapi)
self._cell_type = 'api'
3. nova.compute.cells_api.ComputeCellsAPI.create调用nova.compute.api.API.create,继续trace执行:self.compute_task_api.build_instances
这里self._compute_task_api不为空,因此执行ConductorTaskRPCAPIRedirect(self.cells_rpcapi).build_instances;
4. 3中做了redirect,实际调用self.cells_rpcapi.build_instance,即nova.cells.rpcapi.py中CellsAPI的build_instance, 要进行rpc call了,rpc.getclient发出的message给
nova-cell收到,这时还在同一个cell中(parent cell,或者api cell中),nova-cell收到后调用nova.cells.manager.py中的CellsManager处理;
5.继续trace,
CellsManager中build_instance执行:
our_cell = self.state_manager.get_my_state()
self.msg_runner.build_instances(ctxt, our_cell, build_inst_kwargs)
其中:
self.state_manager = cell_state_manager()(即nova.cells.state.CellStateManager)
在CellStateManager的__new__中有:
if cells_config is _unset:
cells_config = CONF.cells.cells_config #可以在例如/etc/nova/cells.json中写cell的情况,同时在配置文件中指定
if cells_config:
return CellStateManagerFile(cell_state_cls)
return CellStateManagerDB(cell_state_cls) #用nova-manage创建修改的结果在db中
根据不同情况返回CellState,CellState信息包括:
self.name = cell_name
self.is_me = is_me
self.last_seen = datetime.datetime.min
self.capabilities = {}
self.capacities = {}
self.db_info = {}
# TODO(comstud): The DB will specify the driver to use to talk
# to this cell, but there's no column for this yet. The only
# available driver is the rpc driver.
self.driver = rpc_driver.CellsRPCDriver()
self.msg_runner = messaging.MessageRunner(self.state_manager)
执行:
message = _TargetedMessage(self, ctxt, 'build_instances',method_kwargs, 'down', target_cell)
message.process()
在这里,关于cell处理的细节正式开始了,待续。。。