pythongrpc并发性能_机器学习模型python在线服务部署的两
种实例
背景
众所周知python在机器学习实践中的应⽤⼴泛深⼊,⽽在我们业务中的应⽤集中在提供线上实时风控输出服务,⽐如国内业务的模型在线服务架构和海外业务的后台决策引擎架构。这两种应⽤的结合就要求我们考虑如何⾼效安全便捷地来实现模型的在线部署,为上游提供服务。
在我们的考虑中,⽆论是代码复杂程度和业务场景,还是语⾔本⾝的特点,模型部署都有趋于向微服务架构转型的趋势和需要。⼀⽅⾯,需要进⾏代码分离来明确责任分⼯提⾼开发效率和容错性。另外⼀个⽅⾯,python在CPU密集型的应⽤中表现是⽆法令⼈满意的。为了使⽤协程来提⾼异步性从⽽处理更多的并发请求,最直接地就是将CPU密集转化为IO密集,因为Python天⽣就适合IO密集型的⽹络应⽤。
因此,我们⽣产中将模型计算抽取为model_lib代码库,并且通过微服务online_model进⾏交互。这⾥我们调研过两种模型部署的⽅式,最终选择了第⼀种。
⼀、基于flask框架进⾏模型部署
Flask是⼀个轻量级的可定制框架,具有灵活、轻便且⾼效的特点,并且是标准的wsgi接⼝框架,易于扩展和维护。
1. 为什么选⽤nginx+uwsgi+flask这种技术架构
1)    Uwsgi搭配nginx性能快,内存占⽤低,⾼度可定制,⾃带详尽⽇志功能,⽀持平滑重启。
2)    Flask完全兼容了wsgi标准; 微框架,扩展性强; 完全基于unicode,不需处理编码问题;⾃带服务可独⽴做单元测试及开发。
3)    我们客户端采⽤了tornado协程,已经实现了将cpu计算转为io操作,服务端完全是CPU密集的模型计算,不会释放进程,异步框架保持⼤量⽂件描述符状态耗费内存,因此不适⽤异步IO框架。
2. 业务流程框架
3. 部署⽅式:
部署⽅式采⽤nginx+uwsgi+flask的⽅式,uwsgi可直接接受socket⽽不是http请求提⾼性能,再将服务转发给flask框架,这⾥注意flask 此类wsgi标准接⼝的服务框架⽐如djangoweb.py在⽣产中⼀般不使⽤⾃带服务,⽽是在上层部署uwsgi或者gunicorn作为服务器来进⾏服务转发,上层再⽤nginx来做负载均衡,这样可以提⾼服务稳定性和性能。
4. 代码⽰例:
uwsgi服务配置:[uwsgi]
# 监听端⼝
socket=127.0.0.1:8200
# 进程数
processes=20
;async=4
;threads=2
;enable-threads = true
# 运⾏的⽬录
chdir = /home/rong/www/online_model
# wsgi⽂件
wsgi-file = model_main.py
callable=app
# 是否要有主进程
master = true
# 后台运⾏及其打印的⽇志
daemonize = /home/rong/www/log/uwsgi.log
# 主进程pid⽂件
pidfile = /home/rong/www/log/online_model/pid/uwsgi.pid
# ⽇志切割⼤⼩
log-maxsize = 5000000
# 不记录请求信息的⽇志。只记录错误以及uWSGI内部消息到⽇志中。
disable-logging = false
# 超时时间
http-timeout= 3
# 传输数据⼤⼩限制
buffer-size = 1048576
# 每个进程单独加载
lazy-apps = true
flask服务关键代码:import importlib
import json
import cProfile
import pstats
import StringIO
import time
import traceback
from flask import Flask, request
from common import rong_logger
from common.global_variable import StaticCacheClass
import autopath # 不能去掉
app = Flask(__name__)
# 这⾥是模型代码库的统⼀⼊⼝,模型代码库中是通过抽象类实现的规范化的模型代码实例,通过此服务提供调⽤,也通过离线调度进⾏跑批任务。保证线上线下模型调⽤⼀致性
online_model_main = importlib.import_module('online_model_main')
MUST_PARAMS = ['resource_id', 'feature_dict']
SUCCESS_STATUS = 0
ERROR_STATUS = 1
# 路由函数只允许post请求
@ute("/", methods=['POST'])
def model_main():
uniq_id = '[%s][%s]' % (('resource_id', ''), request.url)
try:
status, msg, params = _check_params(request)
if status != SUCCESS_STATUS:
(uniq_id + 'params error, detail: %s' % msg)
status, msg, result = status, msg, None
else:
resource_id, feature_dict = params['resource_id'], json.loads(params['feature_dict'])
status, msg, result = online_model_main.main(resource_id, feature_dict, request, rong_logger)
rong_logger.info(uniq_id + '[%s][%s][%s]' % (status, msg, result))
except Exception as e:
(uniq_id + 'error: %s, detail: %s' % (str(e), traceback.format_exc()))
status, msg, result = 5, 'online_model_error:' + str(e), None
return _get_response(status, msg, result)
模型代码库模型实例:
其中 XgboostExecutor类是基于xgb模型抽象类实现的类,通过它来实例化⼀个模型对象,给flask应⽤
提供调⽤。具体我们不再深究,有兴趣可以再写⼀个专题来介绍模型代码库的部署。# -*- coding:utf-8 -*-
# !/usr/bin/python
import logging
import os
from executor.src.load_helper import read_cur_path
boost_model_executor import XgboostExecutor
logging.basicConfig(level=logging.INFO, format='%(asctime)s:%(message)s')
[model_path, features_path,feature_importance_path] = map(
read_cur_path, ["xgb_model", "feature_list","feature_importance"]
)
java调用python模型
model = XgboostExecutor(model_path, features_path,
feature_check_white_list=["n21_score"],
white_or_weight=False,
feature_check_weight_limit= 1,
feature_importance_path=feature_importance_path,
manager="qutianhang@xx",
developer="qutianhang@xx",
correlation="negative")
5. 性能⽐对
微服务改造后20并发请求模型:
微服务改造前20并发请求模型:
本机测试并发性能就提⾼了20%,但注意这是在⾼并发的情况下,就单条请求来看,微服务并不能显著提⾼性能。
⼆、 基于grpc进⾏在线模型部署
在 gRPC ⾥客户端应⽤可以像调⽤本地对象⼀样直接调⽤另⼀台不同的机器上服务端应⽤的⽅法,能够更容易地创建分布式应⽤和微服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义⼀个服务,指定其能够被远程调⽤的⽅法(包含参数和返回类型)。在服务端实现这个接⼝,并运⾏⼀个 gRPC 服务器来处理客户端调⽤。在客户端拥有⼀个存根能够执⾏在服务端实现的⼀样的⽅法(这个⽅法就类似于接⼝)
1. 为什么选⽤grpc进⾏模型部署1)grpc使⽤ProtoBuf来定义服务、请求返回的数据格式,压缩和传输效率⾼,语法简单,表达⼒强。(如下为ProtoBuf的序列化和反序列话性能表现)
2)grpc可⽀持tensorflow serving的接⼝调⽤,tensorflow完成模型训练和部署后,可提供服务接⼝,给grpc进⾏调⽤。实现⽅便,⾼
效,⾃带版本管理、模型热更新等,很适合⼤规模线上业务,是我们下⼀步模型部署的技术⽅向。
3)gRPC⽀持多种语⾔,并能够基于语⾔⾃动⽣成客户端和服务端功能库。
2. 部署⽅式(业务流程与之前相同)
3. 服务发现与负载均衡
4. 开发流程
客户端:
服务端:
三、 两种⽅式线上模型部署对⽐
1)    grpc使⽤protbuf更加复杂,需要在客户端服务端均保留protbuf⽂件并做校验,⽽flask只需要做好统⼀的接⼝标准规范即可。
2)    grpc使⽤http2.0更适⽤移动端的在线模型预测,或者基于tensorflowd的⼤规模线上模型部署和预测,flask更适⽤后端⾯向服务的⼿动模型部署和预测。
3) grpc节省数据空间,但与python交互需要做json和protbuf数据转换,flask兼容wsgi标准,适⽤于RESTful类服务,但数据传输占⽤空间较⼤。
关于⼀教程⽹
本站⽂章仅代表作者观点,不代表本站⽴场,所有⽂章⾮营利性免费分享。
本站提供了软件编程、⽹站开发技术、服务器运维、⼈⼯智能等等IT技术⽂章,希望⼴⼤程序员努⼒学习,让我们⽤科技改变世界。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。