通过深度学习训练出的神经网络模型在被部署在云上服务器后,如何被条件适时触发从而被调用?这个问题之前困扰了我几天,并不清楚其他更高效的方法,这个方法是自己唯一能想到的
简述一下我之前小项目的部分需求,在别处的系统会传输数据到云上服务器的SQL数据库,需要模型在检测到数据库有新内容传输时,把数据取出,在处理完数据后把结果输出回数据库存储,前端页面再对数据库里的结果进行查询
但为什么不让系统直接把数据传输给模型预测?这是因为神经网络模型在处理一份数据期间不会处理此时传输过来的另一份数据。如果直接传输给模型,则可能会让模型跳过一些未被处理的数据。这时就需要数据库把未处理的内容进行缓存,模型处理完一条数据后检测到仍有未处理的数据就会依次查询取出数据
本文用到的调用方法是通过一个 Python事件监听程序 对SQL数据库表中有新内容插入的事件进行监听,在监听到有新内容插入后再唤醒模型,并且传入需要处理数据的编号 ID,从而让模型知道该处理哪行的数据
这时候会有一个思考,如果我让模型一直处于while的循环当中,那么只要数据库的表里有新内容插入就会被传输到模型进行处理,这就不需要事件监听程序的辅助了是吗?
这确实也是一种方法,但模型要面对并发的情况,所以系统需要多进程执行神经网络模型,此时如果不受监听程序的有序分配,那么不同进程的模型就很可能处理同一条数据,针对同一份数据处理出的多份结果会被传输回数据库,前端查询的时候可能就查询到多个结果,这并不符合预期
Python事件监听代码:
import er as er
import pymssql
import os
import shutil
import time
import datetime
from ipykernel import connect
conn = pymssql.connect(server='123.123.123.123', port='1438', user='SA', password='1234Qwer', database='TestDB')
if conn:
print("连接成功!") #服务器关闭时会导致连接不成功
global_var = 1 #定义全局变量
seconds = 2 #相隔2秒对数据库中operation表进行查询
servicelist = [
"MSSQLSERVER"
]
while True:
id = 1 #默认从表的第一行开始查询
try:
now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
for service in servicelist:
cursor = connect.cursor() # 创建一个游标对象,python里的sql语句都要通过cursor来执行
sql = '''
select * from 表 where id = XXX;
''' #查询数据库中表中的数据
cursor.execute(sql) # 执行sql语句
row = cursor.fetchall() #读取查询结果
global_var = row
if row != global_var: #如果前一次查询到的数据与本次查询的不符,代表该表有新数据传入,实现对sql server的实时监控
id += 1
os.system("python3.7 启动模型的文件") #启动模型
counter = seconds
while counter > 0:
print('wating for ', counter, 'seconds...')
time.sleep(1)
counter = counter - 1
except er:
print(er)
这份代码其实缺少了如何有效分配未处理的数据给到空闲可用的进程的功能模块,当时我是想用哈希的方式需求寻找空闲的进程。在实际工作面试中,如果面试官听到这种方法估计就直接结束了。并且在 if row != global_var: 这段代码里面还需要让数据库里待处理的编号 ID 传给模型,让模型从数据库表中取出对应的数据,也可以的直接把监听程序取出的数据直接传给模型进行处理
监听程序会在重启后丢失原先处理到的数据位置,我们可以创建运行日志记录每次调用模型时的数据位置,每次重启后程序会先读取运行日志最后一行数据来定位到重启前处理到的数据位置。如此一来,就不必担心服务器重启导致处理进度被重置的问题
本文中的模型原本是 NLP语言模型 ,所以取出的数据只是文本字段,如果是视觉模型要被调用,这个方法修改一下也应该适用