Ghan
2020 年6 月 1 日 14:04
1
我正在尝试从现有论坛进行导入测试。我们需要导入约 2500 万条帖子(包括普通帖子和私密对话)。为了加快速度,我创建了多个导入脚本副本并行运行,以分担话题加载任务。起初几天一切正常,但随着时间的推移,我注意到每个进程的内存使用量缓慢增加,最终达到约 2 GB。随后,服务器内存耗尽,在导入约 1600 万条帖子时杀死了 MySQL 源数据库。
我已将系统内存从 24 GB 提升至 32 GB,但现在即使尝试重新启动一个导入进程并从断点继续,该进程在开始导入任何帖子之前就会立即占用约 10 GB 内存。此前我可以同时运行 8 个导入进程,而现在在更大的内存池中只能运行 2 个。为什么从全新安装启动与在失败后重启导入之间会出现如此巨大的内存使用差异?有什么方法可以减少内存占用,从而再次加快导入速度吗?配备 128 GB 至 256 GB 内存的服务器成本过高(且导入完成后不再需要),而仅运行 2 个导入进程意味着导入将需要数周才能完成。
Falco
(Falco)
2020 年6 月 1 日 14:09
2
听起来像是正则表达式陷入了死循环之类的情况。请打印调试信息,并在导入时跳过有问题的行。
Ghan
2020 年6 月 1 日 14:16
3
内存占用似乎全部发生在导入脚本启动时的“正在加载现有帖子……”(或主题)部分,而不是在实际的帖子处理过程中。据我观察,该部分正在从数据库中提取帖子和主题信息,按理说不应涉及任何正则表达式。
@posts 和 @topics 变量似乎用于诸如“topic_lookup_from_imported_post_id”方法等操作。这说得通,但在脚本初次运行时,内存占用从未接近我现在看到的水平,而这些方法仍然可以正常工作。
pfaffman
(Jay Pfaffman)
2020 年6 月 1 日 14:26
4
你看过批量导入脚本吗?它们的内存占用可能更小。
不过确实,导入脚本会在内存中保留一个旧用户、主题和帖子 ID 到新 ID 的映射,这会占用大量内存,尤其是当你需要多个副本时。
你明白吧,运行完首次导入后,你只需再次运行以导入新数据,那时速度会快得多,对吧?所以,虽然首次导入可能需要等待一个月,但最终的导入不会花那么长时间。
Ghan
2020 年6 月 1 日 14:35
5
pfaffman:
你查看过批量导入脚本了吗?
我不知道有任何批量导入脚本。这些脚本是在 import_scripts 目录中的某个位置吗?
是的,这正是我遇到困难的地方。在首次导入期间,同时运行 8 个导入进程时情况还算不错,直到系统内存耗尽。现在,当我尝试重新启动导入进程并从断点继续时,每个进程占用的内存大约是首次崩溃时的 5 倍。
我们需要完成一次完整的导入,以便进行适当的测试,并为实际迁移的时间设定预期。目前,我仍然不清楚在性能等方面会有什么预期。此外,我还注意到,即使帖子数量达到 1600 万,数据库的大小已经比当前数据库大了 50% 以上——这有点令人惊讶。漫长的导入时间并不意味着无法完成,但如果预期是以“天”而不是“周”为单位,那肯定会方便得多。
pfaffman
(Jay Pfaffman)
2020 年6 月 1 日 14:42
6
请参阅 https://github.com/discourse/discourse/tree/master/script/bulk_import。
对于主题和帖子而言,实际上并行导入并不可行,因为如果主题及其所有之前的帖子尚未导入,就无法导入该主题中的帖子。我猜你可以为帖子和主题设置并行进程,但除非重写脚本以一次性拉取某个主题下的所有帖子(从而实现并行导入),否则无法对帖子进行并行导入;这当然是可以实现的,但我使用过的任何脚本都不是这样工作的。不过,你仍然会面临它们需要在内存中维护旧 ID 到新 ID 映射的问题。
导入 2500 万条帖子并不方便。
Ghan
2020 年6 月 1 日 15:02
7
这正是我正在做的。我已将主题拆分,使得每个主题仅由一个进程处理。这种拆分并非完美,但速度比单个线性进程快数倍。
[quote=“pfaffman, post:6, topic:153471”]
但你仍然会遇到它们在内存中保留“旧 ID 到新 ID
pfaffman
(Jay Pfaffman)
2020 年6 月 1 日 23:26
8
Ghan:
每个进程是否只维护其已导入帖子的映射?
我认为是这样。其他进程将无法正常工作,因为它们缺少由其他进程导入的那些天数据。我认为你目前的做法行不通。
你需要查看批量导入脚本,或者重写 base.rb,以其他方式跟踪与导入 ID 的链接。
你花在调试代码上的时间很可能比直接等待还要多。单进程 CPU 速度是提升速度的最佳途径。
Ghan
2020 年6 月 2 日 00:28
9
到目前为止,我还没发现这种方法有什么问题,不过我担心在帖子导入之后的一些步骤可能会出现一些问题。我可能需要确保在那之后所有操作都停止,然后采用单线程执行,以确保其余部分能够干净利落地处理。话虽如此,你提出的关于以不同方式处理导入 ID 链接的建议,无论如何可能都是个好主意。在脚本运行期间将任意大量数据保存在某些变量中,效率并不高。