RoaringBitmap插件能将ElasticSearch过滤性能提高 10 倍


Java中更好地压缩位图、位集。通常用作快速数据结构,如果没有压缩它们可能会使用太多内存。RoaringBitmap性能往往优于传统的压缩位图,例如 WAH、EWAH 或 Concise。特点:

  • 非常快的随机访问
  • 良好的压缩比
  • 快速计算
  • 快速序列化

以下列方式工作:
它将数据分成 2^16 个整数的块(例如,[0, 2^16), [2^16, 2 x 2^16), ...)。在块中,它可以使用未压缩的位图、简单的整数列表或运行列表。无论它使用什么格式,它们都允许您快速检查值是否存在(例如,使用二进制搜索)。
这将如何改善您的整体系统:
  • 要传输的数据更少——不仅从客户端到服务器,而且在 ES 节点之间。
  • 更少的内存使用——我们的客户端将使用更少的内存,但最重要的是,ES 节点也将使用更少的内存。
  • 更少的磁盘空间——如果这些列表需要保存在数据库中的某个地方,使用 RoaringBitmaps 保存它可以节省大量空间。
  • 高效查找——Roaringbitmaps 对于内存中查找来说非常高效和快速

下面是ElasticSearch 插件代码:
@Override
public FilterScript newInstance(LeafReaderContext context) throws IOException {
    final byte[] decodedTerms = Base64.getDecoder().decode(terms);
    final ByteBuffer buffer = ByteBuffer.wrap(decodedTerms);
    RoaringBitmap rBitmap = new RoaringBitmap();
    rBitmap.deserialize(buffer);

    return new FilterScript(params, lookup, context) {

        @Override
        public boolean execute() {
            try {
                final ScriptDocValues.Longs fieldNameValue = (ScriptDocValues.Longs)getDoc().get(fieldName);
                final int docId = (int)fieldNameValue.getValue();    

                if (opType.equals("exclude") && rBitmap.contains(docId)) {
                    return false;
                }
                else if (opType.equals(
"include") && !rBitmap.contains(docId)) {
                    return false;
                }
                return true;

            } catch (Exception exception) {
                throw exception;
            }
        }
    };
}

插件库Github