es数据防篡改方案通过_version和runtime fields特性来实现

1、基本概念

1.1version

_version是es索引的一个隐藏字段,创建索引时自动生成,且初始值为1,它顾名思义就是一个版本号,当索引发生改动的时候会自动加1;想查看它的值,需要在搜索时加上version=true

举例:

建立一个只有一个字段的索引并填充几条数据

DELETE news_00001
PUT news_00001
{
  "mappings": {
    "properties": {
      "tetttttt": {
        "type": "integer"
      }
    }
  }
}

POST news_00001/_bulk
{"index":{"_id":1}}
{"tetttttt":500}
{"index":{"_id":2}}
{"tetttttt":100}
{"index":{"_id":3}}
{"tetttttt":900}
{"index":{"_id":4}}
{"tetttttt":600}

查看它的version 

GET /news_00001/_search?version=true

修改后再看version

PUT /news_00001/_doc/1
{
  "tetttttt":108
}

GET /news_00001/_search?version=true

1.2runtime fields(7.11后的新特性)

runtime fields叫运行时字段,想了解它不如先看个场景;

同样以上面1.1创建的索引为例;如下命令就是给索引添加了一个runtime fields,叫做isUpdate:他的意思呢就是判断这个索引是否被修改过,是的话赋值为1,没有的话是0

PUT news_00001/_mapping
{
  "runtime": {
    "isUpdate": {
      "type": "keyword",
      "script": {
        "source": "if (doc['_version'].value < 2 ) emit('0'); if (doc['_version'].value >= 2) emit('1');"
      }
    }
  }
}

普通查询,发现没有isUpdate这个字段

GET news_00001/_search?version=true
{
  "query": {
    "match": {
      "isUpdate": "1"
    }
  }
}

runtime fields想要被查到,需要类似如下命令

GET news_00001/_search?version=true
{
  "fields": [
    "*"
  ],
  "query": {
    "match": {
      "isUpdate": "1"
    }
  }
}

以上两步可以一步实现,查询时建立映射关系

GET news_00001/_search?version=true
{
  "runtime_mappings": {
    "isUpdate": {
      "type": "keyword",
      "script": {
        "source": "if (doc['_version'].value < 2 ) emit('0'); if (doc['_version'].value >= 2) emit('1');"
      }
    }
  },
  "fields": [
    "*"
  ],
  "query": {
    "match": {
      "isUpdate": "1"
    }
  }
}

至此我们是不是已经感受到runtime fields的妙处了,它十分方便的帮助已创建的索引添加字段;而且它还能随时修改字段类型,这在7.11版本之前对于es来说一直是个麻烦的问题,涉及到字段类型的修改就要重新创建索引,迁移数据,删除老索引这一套操作。,此外它同样能够作为普通字段一样去查询,去做聚合。

优点:

非常灵活,需要时用,不需要时随时可以删除。

可以先创建索引,填入数据再去定义字段,它并不占用存储。

缺点:

万事都有两面性,获得空间的代价就是牺牲了时间,它每次查询时这里面的映射关系是查询时额外计算处理的,这就影响了性能。

2.方案介绍

我们在看完上面对_version的介绍就能理解到为什么我想用它来做数据防篡改,我通过定时监控_version的变化,及时发现数据已被修改。

但是碰到一个问题就是,_version不能作为查询条件去搜索,这就意味着我需要把数据库所有数据都遍历一遍去判断_version是否改变,当数据量庞大的时候那肯定是极度低效的;

紧接着runtime fields不就用上了嘛,哈哈建一个新的runtime field,与_version建立映射关系,每次我搜索的时候直接把runtime field作为查询条件即可!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿星_Alex

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值