openstack采用了token认证的机制,各api的调用都会涉及到token的验证问题,使得keystone成为一个性能的瓶颈,如下图所示:
token的验证环节包括:验证请求中包含的token是否有效、过期,该token对应的用户组和用户id,对应的授权服务访问地址等;
性能瓶颈的解决-1:
由于openstack中的各api都是wsgi服务,并且都用到了keystoneclient提供的一个中间件(wsgi filter)auth_token,对应的文件位于:keystoneclient/middleware/auth_token.py。该中间件采用memcache来缓存token的相关信息到本地,从而减少各服务对keystone的直接访问,不过默认情况下缓存并未启用。为此,添加如下配置到nova.conf、cinder.conf,... ...
[keystone_authtoken] auth_uri = http://keystone_server:5000/ auth_host = keystone_server auth_port = 35357 auth_protocol = http admin_tenant_name = service admin_user = nova admin_password = password memcache_servers = 127.0.0.1:11211 token_cache_time = 3600 #token本地缓存的失效时间设置为1个小时。 cache = true
auth_token中间件中,token认证的相关代码片段如下:
try: token_id = cms.cms_hash_token(user_token) cached = self._cache_get(token_id) if cached: return cached if cms.is_ans1_token(user_token): verified = self.verify_signed_token(user_token) data = json.loads(verified) else: data = self.verify_uuid_token(user_token, retry) self._cache_put(token_id, data) return data except Exception as e: self.LOG.debug('Token validation failure.', exc_info=True) self._cache_store_invalid(user_token) self.LOG.warn("Authorization failed for token %s", user_token) raise InvalidUserToken('Token authorization failed')
性能瓶颈的解决-2: (keystone的并行化)
当前的keystone实现中并没有采用并行化的机制,keystone-all运行时分别发起两个进程、绑定到两个socket上,分别处理5000和35357端口上的请求。
#管理端口请求的处理 servers.append(create_server(CONF.config_file[0], 'admin', CONF.bind_host, int(CONF.admin_port))) #业务端口请求的处理 servers.append(create_server(CONF.config_file[0], 'main', CONF.bind_host, int(CONF.public_port))) def serve(*servers): signal.signal(signal.SIGINT, sigint_handler) # for server in servers: server.start()
keystone并行化的patch如下:
https://github.com/peterfeiner/keystone/commit/workers-for-grizzly.patch
大概的修改如下:
(1)引入了多线程下共享的socket
(2)根据配置选项works的大小,发起多个进程处理api的请求
代码修改之后,还需对keystone的配置做适当更新:
keystone默认的token存储后端为基于内存的k-v,范围在一个进程的空间内。并行化之后,多个进程需共享访问token的存储后端,这里采用memcache。
修改keystone.conf,并安装memcache服务
[token] # driver = keystone.token.backends.memcache.Token
测试数据(很粗略的对比)
并行化之前,并发访问keystone以认证token,结果为6.65个请求每秒。
并行化之后为13个请求每秒
系统资源如下:
over