python 写的一个数据库定时迁移同步的脚本。想让他一直运行 如何架构呢

2015-03-04 20:59:10 +08:00
 9xrtp7r1

大家好,请教个问题

目的是 把 数据库里面的orders表里的某个text类型字段里面的信息,进行解析,然后存在这个数据库的另外的几个表里

这个orders表里 那个字段的类型是text 里面的内容,我要取出来,用json解析,然后把解析后的数据,存到这个数据库的其他表 ,方便我后期查询

这个orders表会不定时更新,客户下单,数据就会被插入到orders表里,所以我需要定时获取里面的数据,然后,解析,处理

我之前的方案是用python写了个脚本,每隔5秒,读取orders表,然后把orders表里面最近推送的信息获取到,然后进行逐一解析,入库到另外的表里

现在有几个疑问 请教大家:

1.用什么方式安全的 健壮的 让这个脚本永久运行,并且 能够开机启动
2.用什么方式,能够在我 git pull 拉取最新代码后,这个脚本能自动载入最新的代码 并且运行

ps: 目前我的系统跑在docker里

谢谢

6366 次点击
所在节点    问与答
21 条回复
frankzeng
2015-03-04 21:01:30 +08:00
数据库的触发器?
jokester
2015-03-04 21:09:44 +08:00
1 做成daemon
2 最新的什么代码? 脚本本身的代码?
caixiexin
2015-03-04 21:30:17 +08:00
你是写了个死循环,然后每隔5秒执行一次?
1.如果是linux服务器,可以配置cron,每5秒执行一次脚本,这样貌似更好,而且只要系统启动了就能跑。
2.第二点没明白,是说你这个脚本是通过git同步到服务器上来的,然后你想每次代码一更新服务器上也更新吗?git有push钩子,可以在远程仓库被push后执行一段脚本。
clino
2015-03-04 22:10:03 +08:00
supervisor
sujin190
2015-03-04 22:59:57 +08:00
crontab定时启动,最佳
9xrtp7r1
2015-03-04 23:21:11 +08:00
@frankzeng 谢谢 触发器一开始也考虑过,但我们这边因为一些内部原因 不能用触发器 只能写python脚本
9xrtp7r1
2015-03-04 23:22:44 +08:00
@jokester 谢谢 最新的代码 就是, 代码在正式环境运行, 我在开发机上进行开发 ,可能偶尔需要修改下代码,然后我在开发机上更新了代码,git到github,然后 在正式环境上 git pull拉取下来,我希望当我拉取下来,脚本自动重新运行,运行最新git pull下来的代码
9xrtp7r1
2015-03-04 23:28:30 +08:00
@caixiexin 是的呢,我就是写的死循环, [while Tue ] 服务器是linux的 ubuntu 12.04 64位,

第二点就是 [ 代码在正式环境运行, 我在开发机上进行开发 ,可能偶尔需要修改下代码,然后我在开发机上更新了代码,git到github,然后 在正式环境上 git pull拉取下来,我希望当我拉取下来,脚本自动重新运行,运行最新git pull下来的代码]

如果我按照您的方法,那么 就可以直接实现第二点 谢谢


关于前辈您说的用cron,因为脚本第一次运行 需要执行太多任何,那会不会出现上一个任务在执行过程中,时间到了5秒,又启动了第二个任务呀

比如,有时候要同步的数据太多,那么 从 12:00:00开始 开启一个进程来执行,到了12:00:05第一个进程任务还没有完成, 这时候时间却是过去了5秒,那么cron是还会再新开一个进程吗,那这样我怕冲突呢

还有因为这个东西要连接数据库,我再思考 这样频繁的连接数据库,会不会给数据库带来太多压力

我之前用死循环的方法,只要连接一次数据库即可,但死循环的方法总是让我觉得不放心


多谢前辈指点
9xrtp7r1
2015-03-04 23:28:46 +08:00
@clino
@sujin190

谢谢
sujin190
2015-03-04 23:56:49 +08:00
我觉得你需要的是异步任务,5秒,太频繁了吧
jokester
2015-03-05 00:21:48 +08:00
cron到時間就執行 不管上一個有沒結束
所以你還是要自己加鎖防止競態..和自己包一個daemon差不多
9xrtp7r1
2015-03-05 00:34:26 +08:00
@sujin190 异步任务是什么意思呀 那我修改为10秒吧 :)
9xrtp7r1
2015-03-05 00:34:41 +08:00
@jokester 嗯 那我就用supervisor
caixiexin
2015-03-05 08:36:46 +08:00
@9xrtp7r1 不好意思,忘记crontab最小的时间粒度是到分钟的,好像不符合你几秒钟一次的需求?crontab默认的方式貌似是并发的,也就是说前一次没执行完,下一个时间点还会执行。要实现非并发,貌似要用到进程锁,或者同步锁变量,google到一个帖子,可以按上面的操作http://unix.stackexchange.com/questions/58481/can-a-crontab-job-run-concurrently-with-itself
如果crontab不符合要求,可以用上面几位童鞋说的写成守护进程,然后配置在ubuntu的 /etc/init/rc.conf 文件中开机启动。写死循环不是个好方法,以前也这么干过,然后命令后面加‘&’让它后台运行,跑了一段时间进程自己关掉了(也许权限低是被系统kill了?)

关于同步代码,其实没必要用github绕一圈哦,直接把你的服务器上装git,当成远程仓库,本地git push上去,然后服务器上要触发push钩子还是什么的随便搞都可以,全自动2333
kunimi
2015-03-05 08:55:43 +08:00
Celery Beat来做schedule
再加上Celery Once来保证任务不被重复执行 /t/168417
sujin190
2015-03-05 09:23:55 +08:00
Celery +1
frankzeng
2015-03-05 10:18:14 +08:00
@9xrtp7r1 用脚本去扫表真不是一个好办法,要是表数据过多或是处理过程比较长,超过了5秒,那就比较麻烦了。用crontab,但时间间隔改长一点,每次看一下有没有pid文件,有就结束,没有就执行,这样可以防止重复执行。
Septembers
2015-03-05 12:58:03 +08:00
@9xrtp7r1
如果是MySQL可以利用mysqlbinlog导出增量变化
如果是PgSQL可以利用pg_log导出增量变化
9xrtp7r1
2015-03-05 21:31:21 +08:00
@caixiexin 非常感谢哦
9xrtp7r1
2015-03-05 21:31:58 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/174509

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX