如何用python跟踪我读入数据库的文件?

2024-10-03 02:39:38 发布

您现在位置:Python中文网/ 问答频道 /正文

形势

我从远程数据源获取大量json文件。我把这些文件整理成一个档案,然后把它们读入数据库。如有必要,存档将用于重建数据库。在

json文件被远程生成并定期发送到我的服务器,并且读取过程持续进行。不止一次,我们的服务器在一夜之间或周末断电,这对数据库加载来说是一个巨大的问题,因为进程停止了,我不知道加载了什么,没有加载什么,所以我不得不回滚到以前已知的状态,并从存档中重建。在

为了解决这个问题,我的主加载程序守护进程(用python编写)现在使用logging包来跟踪它加载了哪些文件。加载器守护进程的基本工作流是

  • cp要存档的json文件
  • `rm'原件
  • 将存档副本插入数据库(其MariaDB)
  • 提交到数据库
  • 加载的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)

然后,在处理jsonfile时,我使用

^{pr2}$

数据库加载器是并行运行的,所以我最初选择logging包作为其内置的并发保护。有各种各样的数据库;不是每个数据库都从json文件中提取所有数据。一些包含更多信息的数据库时间较短,通常为一到两个月。在这种情况下,在一个给定的数据库中有一个包含所有json文件的日志文件是很好的,因此如果我想在其中添加一些内容,我就不必担心那里已经有什么了,日志文件正在跟踪。在


问题

一年过去了。我一直在获取json文件。我现在每月收到大约一百万个文件。在处理每个文件名时,对其进行文本记录是很笨拙的,但目前仍然可以工作。有多个数据库,但对于最大的数据库,日志文件超过半GB。我觉得这个日志解决方案在很长时间内不会很好地工作。在

当每个数据库有超过1000万个文件名时,python中有哪些选项可以跟踪哪些文件名已插入到数据库中,并且还在不断增加?


Tags: 文件服务器log数据库jsonformat远程进程
3条回答

一种方法是将文件记录在数据库本身的表中,而不是文本日志文件中。如果您为import date或file name等添加了一些列,那么当您需要从这些日志中查找信息时,这可能会为您提供一些灵活性,但是,它也允许您执行定期维护(例如,如果您知道不需要查看那些记录,那么删除已经存在几个月的日志记录)。在

如果您决定继续使用基于文本的日志文件,那么可以考虑将它们拆分,这样就不会产生一个巨大的单块日志文件。当您安装像Apache这样记录大量数据的东西时,您会看到它自动设置log rotation来定期压缩和归档日志文件。。。在

项目1:

Foreach file in input directory
    INSERT IGNORE into database the MD5 of the file
    "mv" the file to the archive directory

程序2,一个“保持活力”的程序。在

它每分钟通过cron运行并尝试启动程序1,但如果程序1已经在运行,则不要启动它。在

注意事项:

  • “mv”和“cron”假设为Unix。如果使用Windows,请执行相应的操作。在
  • “mv”是原子的,因此该文件将位于另一个目录的一个目录中;无需知道它是否“已处理”。(所以,我想知道为什么你甚至有一个数据库表??)在
  • 既然INSERT和{}不能实际地“原子”地完成,所以我的计划是安全的:IGNORE。在
  • “is it running”可以通过多种方式处理,在程序1或程序2中。在
  • 您可以向包含md5的表中添加时间戳和/或文件名;无论您喜欢什么。在
  • 由于在一个目录中包含10K个文件不是一个好主意,所以您应该使用我所设想的一对平面目录之外的东西。在

你每3秒只能得到1个文件。这不是一个沉重的负担,除非文件是巨大的。然后它就变成了I/O问题,而不是数据库问题。在

我有一种感觉,要么我错过了一个隐藏的“要求”,要么你是格外偏执。我真不明白你要怎么处理这些文件。在

您没有说明您使用的是哪种类型的数据库,但一般的做法是

1)对每个json文件进行哈希。SHA256可广泛使用。如果您关心性能,请参阅本文https://softwareengineering.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed

2)使哈希字段成为数据库上的唯一键,然后在执行其他操作之前尝试插入它。如果不能,则记录已存在,事务将中止

相关问题 更多 >