我从远程数据源获取了大量的json文件。我将这些文件组织到一个存档中,然后将它们读入数据库。如有必要,存档用于重建数据库。
json文件是远程生成的,并定期发送到我的服务器,并且读入过程不断发生。不止一次,我们在一夜之间或周末对我们的服务器造成了电力损失,这对于数据库加载来说是一个巨大的问题,因为这些过程停止了,我不知道已经加载了什么以及什么没有加载#39 ;所以我不得不回滚到一些先前已知的状态并重建出档案。
要解决此问题,我的主加载程序守护程序(用python编写)现在使用logging
程序包来跟踪它加载的文件。加载程序守护程序的基本工作流程是
cp
json文件归档我并不担心数据库中的重复,但我不想要差距;也就是说,存档中不在数据库中的东西。到目前为止,这种方法似乎可以防止出现任何差距。
对于我的日志记录,它基本上看起来像这样。守护进程启动时会收到一组收到的文件'名称,它检查已加载到目标数据库的重复项,然后加载所有非重复项。可以从我的远程数据源获取重复项。
def initialize_logs(filenames, destination)
try:
with open("/data/dblogs/{0}.log".format(destination), 'r') as already_used:
seen = set([line.rstrip("\n") for line in already_used])
except FileNotFoundError:
print("Log file for {0} not found. Repair database".format(destination))
quit()
fnamelog = logging.getLogger('filename.log')
fnamelog.setLevel(logging.INFO)
fh = logging.FileHandler("/data/dblogs/{0}.log".format(destination))
fh.setLevel(logging.INFO)
fnamelog.addHandler(fh)
然后,当我处理jsonfiles时,我使用
记录添加的每个文件fnamelog.info(filename)
数据库加载器是并行运行的,所以我最初选择了logging
包来实现其内置的并发保护。有各种各样的数据库;并非每个数据库都从json文件中提取所有数据。一些信息量较多的数据库时间较短,通常为一到两个月。在这种情况下,拥有一个包含给定数据库中所有json文件的日志文件是很好的,所以如果我想在其上添加一些,我不必担心已经存在的内容,日志档案正在跟踪。
一年过去了。我一直在获取json文件。我现在每月收到大约一百万个文件。处理时每个文件名的文本记录是笨拙的,但它现在仍然有效。有多个数据库,但对于最大的数据库,日志文件超过半GB。我觉得这种日志记录解决方案不会再运行得太久了。
当每个数据库有超过1000万个文件名并且正在上升时,python中有哪些选项可用于跟踪已插入数据库的文件名?
答案 0 :(得分:1)
一种方法是将文件记录在数据库本身的表中而不是文本日志文件中。如果您为导入日期或文件名等添加了一些列,那么在您需要时可以为这些日志查找信息提供一点灵活性,但它也可以让您执行定期维护(如例如,如果您知道不需要查看那些日志记录,则删除超过几个月的日志记录。
如果您决定继续使用基于文本的日志文件,您可能会考虑将它们分解,以便您不会使用巨大的单片日志文件。当您安装Apache等记录大量数据的内容时,您会看到它会自动设置log rotation以定期压缩和存档日志文件...
答案 1 :(得分:1)
您没有说明您使用的数据库类型,但一般方法是
1)制作每个json文件的哈希值。 SHA256广泛可用。如果您担心效果,请参阅此帖子https://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed
2)使哈希字段成为数据库中的唯一键,在执行其他操作之前,请尝试插入它。如果您不能记录已存在且事务将中止
答案 2 :(得分:0)
计划1:
Foreach file in input directory
INSERT IGNORE into database the MD5 of the file
"mv" the file to the archive directory
计划2,a"保持活力"程序
它每分钟都会通过cron
运行并尝试启动程序1,但如果它已在运行,则不要启动它。
注意:
INSERT
和mv
无法实际完成"原子地",这就是为什么我的计划是安全的:IGNORE
。每3秒钟只能获得大约1个文件。除非文件很大,否则这不是重负荷。然后它成为I / O问题,而不是数据库问题。
我有一种感觉,要么我错过了一个隐藏的要求,要么你是一个额外的偏执狂。我真的不明白你需要对这些文件做些什么。