如何解决rocksdb写停顿,多次写入相同的数据
首先,我必须解释一下我们的设置,因为它与带有raidgroups的普通数据库服务器完全不同。通常,我们的客户购买的服务器是HP DL 380 Gen10之类的服务器,该服务器具有两个300 GB HDD(不是SSD),这些HDD配置为RAID 1并运行Windows。
我们在这里仅管理其他存储的元数据,以便客户可以向我们询问并在这些大型存储中查找其信息。
由于我们的旧数据库始终损坏,因此我们搜索了一个新的更稳定的数据库,该数据库也没有那么大的开销,并找到了当前版本为6.12.0的rocksdb。
不幸的是,它运行了几个小时后,由于写入停顿,似乎将我的程序阻塞了很多分钟:
2020/10/01-15:58:44.678646 1a64 [WARN] [db\column_family.cc:876] [default]
Stopping writes because we have 2 immutable memtables (waiting for flush),max_write_buffer_number is set to 2
我对机器的写工作量是否过多感到正确吗?
我们的软件是一项服务,每秒最多可从多达2000个不同的服务器中检索至少一个更新(如果可能,将来可能会增加限制)。在大多数情况下,相同的数据库条目仅会再次更新/写入,因为条目内的信息之一是相应服务器的当前时间。当然,我可以尝试减少将数据写入硬盘的频率,但是如果客户请求我们提供此数据,则我们的信息将不是最新的。
所以我的问题是:
-
我假设当前每个写请求都已真正写入磁盘,是否有一种方法可以启用某种类型的缓存(或者如果不足够,则可以增加其大小?),以便不会减少写入数据的次数到硬盘,但是读取请求会从内存中返回正确的数据?
-
我还看到有一个合并运算符,但是我不确定此合并何时发生?是否已经存在如1.下提到的缓存,并且数据收集了一段时间,然后合并然后写入HDD?
-
在这种情况下还有其他优化方法可以帮助我吗?
欢迎任何帮助。预先感谢。
如果可能有趣的话,还有更多日志行:
** File Read Latency Histogram By Level [default] **
** Compaction Stats [default] **
Level Files Size Score Read(GB) Rn(GB) Rnp1(GB) Write(GB) Wnew(GB) Moved(GB) W-Amp
Rd(MB/s) Wr(MB/s) Comp(sec) CompMergeCPU(sec) Comp(cnt) Avg(sec) KeyIn KeyDrop
L0 2/0 17.12 MB 0.5 0.0 0.0 0.0 0.4 0.4 0.0 1.0 0.0 81.5 5.15 0.00 52 0.099 0 0
L1 3/0 192.76 MB 0.8 3.3 0.4 2.9 3.2 0.3 0.0 8.0 333.3 327.6 10.11 0.00 13 0.778 4733K 119K
L2 20/0 1.02 GB 0.4 1.6 0.4 1.2 1.2 -0.0 0.0 3.1 387.5 290.0 4.30 0.00 7 0.614 2331K 581K
Sum 25/0 1.22 GB 0.0 4.9 0.8 4.1 4.9 0.7 0.0 11.8 257.4 254.5 19.56 0.00 72 0.272 7064K 700K
Int 0/0 0.00 KB 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00 0.00 0 0.000 0 0
** Compaction Stats [default] **
Priority Files Size Score Read(GB) Rn(GB) Rnp1(GB) Write(GB) Wnew(GB) Moved(GB) W-Amp Rd(MB/s) Wr(MB/s) Comp(sec) CompMergeCPU(sec) Comp(cnt) Avg(sec) KeyIn KeyDrop
Low 0/0 0.00 KB 0.0 4.9 0.8 4.1 4.5 0.3 0.0 0.0 349.5 316.4 14.40 0.00 20 0.720 7064K 700K
High 0/0 0.00 KB 0.0 0.0 0.0 0.0 0.4 0.4 0.0 0.0 0.0 81.7 5.12 0.00 51 0.100 0 0
User 0/0 0.00 KB 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 50.9 0.03 0.00 1 0.030 0 0
Uptime(secs): 16170.9 total,0.0 interval
Flush(GB): cumulative 0.410,interval 0.000
AddFile(GB): cumulative 0.000,interval 0.000
AddFile(Total Files): cumulative 0,interval 0
AddFile(L0 Files): cumulative 0,interval 0
AddFile(Keys): cumulative 0,interval 0
Cumulative compaction: 4.86 GB write,0.31 MB/s write,4.92 GB read,0.31 MB/s read,19.6 seconds
Interval compaction: 0.00 GB write,0.00 MB/s write,0.00 GB read,0.00 MB/s read,0.0 seconds
Stalls(count): 0 level0_slowdown,0 level0_slowdown_with_compaction,0 level0_numfiles,0 level0_numfiles_with_compaction,0 stop for pending_compaction_bytes,0 slowdown for pending_compaction_bytes,0 memtable_compaction,0 memtable_slowdown,interval 0 total count
** File Read Latency Histogram By Level [default] **
2020/10/01-15:53:21.248110 1a64 [db\db_impl\db_impl_write.cc:1701] [default] New memtable created with log file: #10465. Immutable memtables: 0.
2020/10/01-15:58:44.678596 1a64 [db\db_impl\db_impl_write.cc:1701] [default] New memtable created with log file: #10466. Immutable memtables: 1.
2020/10/01-15:58:44.678646 1a64 [WARN] [db\column_family.cc:876] [default] Stopping writes because we have 2 immutable memtables (waiting for flush),max_write_buffer_number is set to 2
2020/10/01-16:02:57.448977 2328 [db\db_impl\db_impl.cc:900] ------- DUMPING STATS -------
2020/10/01-16:02:57.449034 2328 [db\db_impl\db_impl.cc:901]
** DB Stats **
Uptime(secs): 16836.8 total,665.9 interval
Cumulative writes: 20M writes,20M keys,20M commit groups,1.0 writes per commit group,ingest: 3.00 GB,0.18 MB/s
Cumulative WAL: 20M writes,0 syncs,20944372.00 writes per sync,written: 3.00 GB,0.18 MB/s
Cumulative stall: 00:00:0.000 H:M:S,0.0 percent
Interval writes: 517K writes,517K keys,517K commit groups,ingest: 73.63 MB,0.11 MB/s
Interval WAL: 517K writes,517059.00 writes per sync,written: 0.07 MB,0.11 MB/s
Interval stall: 00:00:0.000 H:M:S,0.0 percent
我们的看门狗在互斥体阻塞了几分钟之后导致了一个断点,此后在日志文件中显示了该断点:
2020/10/02-17:44:18.602776 2328 [db\db_impl\db_impl.cc:900] ------- DUMPING STATS -------
2020/10/02-17:44:18.602990 2328 [db\db_impl\db_impl.cc:901]
** DB Stats **
Uptime(secs): 109318.0 total,92481.2 interval
Cumulative writes: 20M writes,0.03 MB/s
Cumulative WAL: 20M writes,0.03 MB/s
Cumulative stall: 00:00:0.000 H:M:S,0.0 percent
Interval writes: 0 writes,0 keys,0 commit groups,0.0 writes per commit group,ingest: 0.00 MB,0.00 MB/s
Interval WAL: 0 writes,0.00 writes per sync,written: 0.00 MB,0.00 MB/s
Interval stall: 00:00:0.000 H:M:S,0.0 percent
** Compaction Stats [default] **
Level Files Size Score Read(GB) Rn(GB) Rnp1(GB) Write(GB) Wnew(GB) Moved(GB) W-Amp Rd(MB/s) Wr(MB/s) Comp(sec) CompMergeCPU(sec) Comp(cnt) Avg(sec) KeyIn KeyDrop
L0 2/0 17.12 MB 0.5 0.0 0.0 0.0 0.4 0.4 0.0 1.0 0.0 81.5 5.15 0.00 52 0.099 0 0
L1 3/0 192.76 MB 0.8 3.3 0.4 2.9 3.2 0.3 0.0 8.0 333.3 327.6 10.11 0.00 13 0.778 4733K 119K
L2 20/0 1.02 GB 0.4 1.6 0.4 1.2 1.2 -0.0 0.0 3.1 387.5 290.0 4.30 0.00 7 0.614 2331K 581K
Sum 25/0 1.22 GB 0.0 4.9 0.8 4.1 4.9 0.7 0.0 11.8 257.4 254.5 19.56 0.00 72 0.272 7064K 700K
Int 0/0 0.00 KB 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.00 0.00 0 0.000 0 0
** Compaction Stats [default] **
Priority Files Size Score Read(GB) Rn(GB) Rnp1(GB) Write(GB) Wnew(GB) Moved(GB) W-Amp Rd(MB/s) Wr(MB/s) Comp(sec) CompMergeCPU(sec) Comp(cnt) Avg(sec) KeyIn KeyDrop
Low 0/0 0.00 KB 0.0 4.9 0.8 4.1 4.5 0.3 0.0 0.0 349.5 316.4 14.40 0.00 20 0.720 7064K 700K
High 0/0 0.00 KB 0.0 0.0 0.0 0.0 0.4 0.4 0.0 0.0 0.0 81.7 5.12 0.00 51 0.100 0 0
User 0/0 0.00 KB 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 50.9 0.03 0.00 1 0.030 0 0
Uptime(secs): 109318.0 total,92481.2 interval
Flush(GB): cumulative 0.410,0.05 MB/s write,0.05 MB/s read,1 memtable_compaction,interval 0 total count
** File Read Latency Histogram By Level [default] **
解决方法
RocksDB确实有一个built-in cache,您可以肯定地探索它,但是我怀疑可以通过增加max_write_buffer_number
或max_background_flushes
configuration parameters来处理您的写入停顿。 / p>
前者将减小要刷新的内存表的大小,而后者将增加可用于刷新操作的后台线程的数量。
仅凭此信息就很难说机器的工作量是否过高,因为有很多活动部件,但我对此表示怀疑。对于初学者,两个后台刷新线程非常低。另外,我显然不熟悉要测试的工作负载,但是由于您没有使用缓存机制,因此只能从此处提高性能。
磁盘写入非常棘手。任何“写入磁盘”的linux应用程序实际上都是在调用write
系统调用,并因此写入中间内核缓冲区,然后在内核认为合适时将其写入目标位置。实际更新磁盘上数据的过程称为回写(我强烈建议阅读Robert Love的Linux System Programming的文件I / O章节以了解更多信息。
您可以使用fsync(2)
系统调用进行调用,以将文件的系统缓存手动提交到磁盘,但是不建议这样做,因为内核通常会知道何时是最佳时机。
在进行任何定制优化之前,我将检出tuning guide。如果为您的工作负载调整配置不能解决问题,那么我可能会考虑采用RAID配置。写停顿是磁盘I / O吞吐量的限制,因此数据条带化可能会给您带来很大的提升,甚至可以根据您选择的RAID配置,为您提供向存储解决方案中添加一些冗余的选项。
无论哪种方式,我的直觉都是每秒2000个连接似乎对于当前机器的CPU甚至是内存来说都太低了。除非每个请求都需要大量工作来处理,否则我怀疑是这样。当然,确保对端点的服务器配置也进行了优化调整也无济于事。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。