在他的演讲中,避免使用 MemStore-本地分配缓冲区,Todd Lipcon 描述了 HBase 中常见的两种世界性垃圾收集案例,特别是在加载过程中; CMS 故障模式和老一代堆碎片带来了。
要解决第一个问题,请通过添加-XX:CMSInitiatingOccupancyFraction
并将其设置为默认值来启动早于默认值的 CMS。从 60%或 70%开始(降低阈值越低,GCing 越多,使用的 CPU 越多)。为了解决第二个碎片问题,Todd 添加了一个实验工具(MSLAB),必须在 Apache HBase 0.90.x 中明确启用(它在 Apache 0.92.x HBase 中默认为上的 )。在Configuration
中将hbase.hregion.memstore.mslab.enabled
设置为 true。有关背景和细节,请参阅引用的幻灯片。最新的 JVM 更好地考虑碎片,因此请确保您运行的是最新版本。在消息中读入,识别由碎片引起的并发模式故障。请注意,启用后,每个 MemStore 实例将至少占用一个 MSLAB 内存实例。如果您有数千个区域或许多区域,每个区域都有许多列族,那么 MSLAB 的这种分配可能会导致很大一部分堆分配,并且在极端情况下会导致您进入 OOME。在这种情况下禁用 MSLAB,或者降低它使用的内存量或每个服务器浮动更少的区域。
如果您的工作量很大,请查看 HBASE-8163 MemStoreChunkPool:使用 MSLAB 时对 JAVA GC 的改进。它描述了在写入负载期间降低年轻 GC 数量的配置。如果您没有安装 HBASE-8163,并且您正在尝试改善年轻的 GC 时间,那么我们需要考虑的一个诀窍 - 我们的梁燮 - 是在 hbase-env.sh 中设置 GC 配置-XX:PretenureSizeThreshold
只是小于hbase.hregion.memstore.mslab.chunksize
的大小所以 MSLAB 分配直接发生在终身空间而不是年轻时代。你这样做是因为这些 MSLAB 分配很可能无论如何都要用于旧版本,而不是在 eden 空间中支付 s0 和 s1 之间的拷贝价格,然后在 MSLABs 之后从年轻到旧代复制。取得了足够的任期,节省了一点 YGC 流失并直接分配到旧版。
长 GC 的其他来源可以是 JVM 本身的日志记录。请参阅消除由后台 IO 流量引起的大型 JVM GC 暂停
有关 GC 日志的更多信息,请参阅 JVM 垃圾收集日志。
还要考虑启用堆外块缓存。这已被证明可以缓解 GC 暂停时间。见 Block Cache