前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >用Elasticsearch存储图片并在Kibana中显示

用Elasticsearch存储图片并在Kibana中显示

原创
作者头像
点火三周
修改2021-03-02 10:07:23
7.8K0
修改2021-03-02 10:07:23
举报
文章被收录于专栏:Elastic Stack专栏Elastic Stack专栏

@Toc

能用Elasticsearch来存储图片吗?有不少朋友都问过这个问题,Elasticsearch作为一个NoSQL数据库,一个搜索引擎,一个大数据存储系统,原则上来说,对于各种结构化,非结构化数据,文本类,非文本类数据都能够存储。即图片也是可以用来存储的,但现实中这种实际的操作方式是不常见的,因为对象存储等基础设施会是一个更低成本的选择。不过,考虑某些综合场景,比如,用户希望只搭建一套大数据系统来支撑不同的使用需求,那么Elasticsearch确实是比Hadoop生态这种包含非常多组件的系统要简单得多。

图片的存储

那么,我们该如何在Elasticsearch进行图片的存储呢?

第一个要解决的问题是我们应该选择何种类型来进行图片的存储。因为图片数据不同于文本数据,其包含的内容是像素点的颜色,位置,大小等相关信息,属于我们无法理解数据类型,因此,不需要对图片数据内容做倒排索引,Keyword,points等用于加速搜索、排序、聚合的数据结构,因此,需要用二进制的方式存储。

而对于图片的元数据,比如,图片的类型,图片的名称,图片中包含的内容(需要通过机器学习算法来提取),图片的向量值,这些属于可搜索内容的,则可以设置为不同的类型,比如:

  • 图片的类型,图片的名称,图片中包含的内容等局可以文本的方式(text type)来进行存储
  • 图片的向量可以用以vector type来进行存储

Binary field type

binary类型接受一个二进制值作为Base64编码的字符串。该字段默认不存储,也不可搜索。

代码语言:txt
复制
PUT my-index-000001
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "blob": {
        "type": "binary"
      }
    }
  }
}

PUT my-index-000001/_doc/1
{
  "name": "Some binary blob",
  "blob": "U29tZSBiaW5hcnkgYmxvYg==" 
}

二进制字段接受以下参数。

  • doc_values 字段是否应该以列存的方式存储在磁盘上,以便以后可以用于排序、汇总或脚本,可配置为 "true "或 "false"(默认)
  • store 字段值是否应与 _source 字段分开存储和检索。可配置为rue 或 false(默认)

图片的摄入 经验证,这部分因为encoding的原因无法正确摄入binary数据

其实图片的存储并不复杂,只需要选择合适的数据类型来对应不同的数据内容即可。主要的问题是在图片的摄入,在默认的Elastic Stack技术栈里,并没有提供专门的工具来进行图片数据的摄入。需要我们做一定的适配

以下,我们通过filebeat进行图片摄入的一个样例。

首先,filebeat默认来说,是以文件为对象对文件里文本类型的数据进行采集的,以行为单位,检查\n等符号来确定一个event的边界。即检测到\n后,采集器会往队列里push一条event (两个\n之间的内容)。而图片,是以文件为单位,每个文件对应一个图片,即文件=图片=event。

因此,我们需要让filebeat能够将整个文件作为一个event来采集就必须借助multilines参数。具体的配置项可参考官方文档。我们针对png图片为例,可通过以下配置来进行采集:

代码语言:txt
复制
filebeat.inputs:
- type: log
  paths:
  - '/Users/lex.li/Documents/elastic/materials/s*.png'
  harvester_buffer_size: 16384000
  fields:
    format: "png"
  multiline:
    pattern: '^?PNG'
    match: after
    negate: true
    max_lines: 100000

processors:
   - dissect:
        tokenizer: "%{key0}/materials/%{filename}.png"
        field: "log.file.path"
        target_prefix: ""
   - drop_fields:
        when:
            has_fields: ['key0']
        fields: ["key0"]
   - drop_fields:
        fields: ["agent","ecs"]

output.elasticsearch:
  hosts: ["http://localhost:9200"]
  username: "elastic"
  password: "changeme"

  indices:
  - index: "images"

  bulk_max_size: 1500
  worker: 3

setup:
  template.enabled: false
  ilm.enabled: false

这里,因为考虑到图片可能很大,我们将单个采集器的buffer和multilines的行数配置得比较大:

代码语言:txt
复制
...
  harvester_buffer_size: 16384000
  ...
    max_lines: 100000

通过dissect processors , 提取一些基本的图片信息,比如文件名和文件类型:

代码语言:txt
复制
  fields:
    format: "png"
···
processors:
   - dissect:
        tokenizer: "%{key0}/materials/%{filename}.png"
        field: "log.file.path"
        target_prefix: ""
   - drop_fields:
        when:
            has_fields: ['key0']
        fields: ["key0"]
   - drop_fields:
        fields: ["agent","ecs"]

存放到名为images的索引中。因为filebeat默认会把内容放在message字段中,我们需要提前设置该字段的类型为binary:

代码语言:txt
复制
PUT images
{
  "mappings": {
    "properties": {
      "message": {
        "type": "binary"
      }
    }
  }  
}

呈现方式如下,我们采集了所有以s开头的png图片

在这里插入图片描述
在这里插入图片描述

采集之后,可以通过Kibana界面查看

在这里插入图片描述
在这里插入图片描述

存储的是图片的数据

在这里插入图片描述
在这里插入图片描述

如果我们需要把这些数据还原回去,还需要从这个json当中,把message里的内容保存为一个文件,并需使用正确的格式扩展名(比如这里的png)。

在Kibana中查看图片

我们可以在Kibana中查看我们搜索的图片。这时需要借助script field。

首先打开索引模式。

在这里插入图片描述
在这里插入图片描述

然后添加脚本字段

在这里插入图片描述
在这里插入图片描述

其格式为URL->图像,这里的URL输入为http服务的地址,可见后文。并且,注意设置一下宽和高

在这里插入图片描述
在这里插入图片描述

创建该字段,内容为 filename.keyword, 并将其通过{{value}}带入到URL中。(见上图)

在这里插入图片描述
在这里插入图片描述

这时,可以在discovery中看到图片的预览:

在这里插入图片描述
在这里插入图片描述

这里需要在图片文件存储的目录启动一个http server:

代码语言:txt
复制
lexlideMacBook-Pro:materials lex.li$ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 图片的存储
    • Binary field type
    • 图片的摄入 经验证,这部分因为encoding的原因无法正确摄入binary数据
    • 在Kibana中查看图片
    相关产品与服务
    对象存储
    对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档