前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >腾讯时序数据库之准实时揭秘

腾讯时序数据库之准实时揭秘

作者头像
腾讯云数据库 TencentDB
发布2019-05-17 11:10:04
1.3K0
发布2019-05-17 11:10:04
举报

点击上方蓝字每天学习数据库

| 本文作者:游成松,腾讯云数据库后台开发,负责腾讯云数据库CTSDB产品的设计、研发、运维等工作。曾负责腾讯云数据库SQLServer、PostgreSQL、TDSQL、Tbase、CynosDB产品的研发工作。


一个理想的查询过程中,新增加或者修改的数据应该能立即被查询到。腾讯时序数据库CTSDB给人的第一印象好像就是如此工作的,而事实上并非如此。那它实际情况是怎么样的呢?

在进行说明之前先大概介绍一下CTSDB处理请求的流程。

在CTSDB和磁盘之间有一层FileSystem Cache的系统缓存,以使得能够更快地处理搜索请求。插入请求到来时document会先被放入到indexing buffer,然后被重写为一个segment直接写入到filesystem cache,这个操作是非常轻量级的,相对耗时较少,之后经过一定的间隔或外部触发后才会被flush到磁盘上,这个操作非常耗时。但只要sengment文件被写入cache后就可以被打开和查询,在短时间内就可以搜到,而不用执行一个flush也就是fsync操作。其请求处理流程如下图:

下面通过一个案例来验证进行观察分析。

新增加一条数据到新创建的索引中。

代码语言:javascript
复制
curl -u root:xxxxxx -XPOST 127.0.0.1:9200/test/test/1 -d '{    "title":"test"}'

为了进行验证,我们修改这条数据,并尝试立即查询它,连续执行下面两行命令。

代码语言:javascript
复制
curl -u root:xxxxxx -XPOST 127.0.0.1:9200/test/test/1 -d '{    "title":"test2"}'curl -u root:xxxxxx -XGET 127.0.0.1:9200/test/test/_search -d '{    "docvalue_fields":[        "title"    ]}'

前面两行命令返回结果如下:

代码语言:javascript
复制
{    "_index":"test@1555344000000_30",    "_type":"test",    "_id":"1",    "_version":2,    "result":"updated",    "_shards":{        "total":2,        "successful":2,        "failed":0    },    "created":false}{    "took":0,    "timed_out":false,    "_shards":{        "total":3,        "successful":3,        "skipped":0,        "failed":0    },    "hits":{        "total":1,        "max_score":1,        "hits":[            {                "_index":"test@1555344000000_30",                "_type":"test",                "_id":"1",                "_score":1,                "_source":{                    "title":"test",                    "timestamp":1556299203460                },                "fields":{                    "title":[                        "test"                    ]                }            }        ]    }}

我们可以看到第1条命令修改数据成功了,返回结果version字段为2,一切正常。但是第2条命令返回的title字段应该返回test2的,但是还是返回修改之前的数据test。

由于CTSDB底层是基于ElasticSearch的,而ElasticSearch的索引是基于Apache Lucene索引的,那我们先来看看Lucene的内部机制,Lucene是如何让新索引的文档在搜索时可用?

索引更新及更新提交

索引新文档时会被写入索引段。不时会有新增的索引段被添加到可被搜索的索引段集合中,Lucene通过创建后续的(基于索引只写一次的特性)segments_N文件来实现此功能。这个过程被称为提交,Lucene会以安全、原子的操作来提交保证数据一致性。

我们回来之前的案例中,尽管第1个命令修改了文档,但它还没有执行提交操作。然而执行了提交操作也不能保证能被搜索到,因为Lucene使用一个叫Searcher的抽象类来执行索引的读取。该类需要被刷新,如果索引更新提交了,但Searcher实例没有重新打开(刷新),那么Searcher察觉不到有新索引段的加入。对于Searcher的刷新间隔时间可以通过refresh_interval来进行设置。

同时在ElasticSearch中提供了refresh端点进行强制Searcher刷新。我们可以在上面两行命令中间加入强制刷新API再来验证。

代码语言:javascript
复制
curl -u root:xxxxxx -XPOST 127.0.0.1:9200/test/test/1 -d '{    "title":"test3"}'curl -u root:xxxxxx -XGET 127.0.0.1:9200/test@1555344000000_30/_refreshcurl -u root:xxxxxx -XGET 127.0.0.1:9200/test/test/_search -d '{    "docvalue_fields":[        "title"    ]}'

上面三行命令返回结果如下:

代码语言:javascript
复制
{    "_index":"test@1555344000000_30",    "_type":"test",    "_id":"1",    "_version":3,    "result":"updated",    "_shards":{        "total":2,        "successful":2,        "failed":0    },    "created":false}{    "_shards":{        "total":6,        "successful":6,        "failed":0    }}{    "took":0,    "timed_out":false,    "_shards":{        "total":3,        "successful":3,        "skipped":0,        "failed":0    },    "hits":{        "total":1,        "max_score":1,        "hits":[            {                "_index":"test@1555344000000_30",                "_type":"test",                "_id":"1",                "_score":1,                "_source":{                    "title":"test3",                    "timestamp":"1556301337152"                },                "fields":{                    "title":[                        "test3"                    ]                }            }        ]    }}

可以看到第3条命令返回的title字段为test3,返回了修改之后的数据test3。

事务日志

在ElasticSearch的索引实现中Apache Lucene能保证索引的一致性,但这不能保证当向索引中写数据失败时不损失数据(例如,磁盘空间不足,设备异常)。另外一个问题是频繁提交(触发一个索引段的创建操作,同时也可能触发索引段的合并)会导致性能问题。ElasticSearch使用事务日志来解决这些问题,事务日志保存所有未提交的事务。当有错误发生时,事务日志会被检查,必要时再次执行某些操作,以确保没有丢失任何更改。事务日志中的信息与存储介质之间的同步被称为事务日志刷新。同样事务日志的刷新间隔可以通过index.translog.flush相关参数进行配置,也可以通过_flush端点进行强制事务日志刷新。

事务日志刷新flush用于保证数据写入磁盘并清空事务日志。Searcher刷新refresh用于搜索到最新的文档。

准实时读取

事务日志给ElasticSearch带来了一个特性:实时读取。实时读取从索引中读取数据时,会先检查事物日志中是否有可用的新版本(未提交版本),如果有就会返回事务日志中的最新版本的文档。

为了演示实时读取,连续执行下面两条语句,第2条语句查询时指定索引文档id来查询,会从事务日志中读取最新的数据。

代码语言:javascript
复制
curl -u root:xxxxxx -XPOST 127.0.0.1:9200/test/test/1 -d '{    "title":"test4"}'curl -u root:xxxxxx -XGET 127.0.0.1:9200/test@1555344000000_30/test/1

上面2行数据返回结果如下:

代码语言:javascript
复制
{    "_index":"test@1555344000000_30",    "_type":"test",    "_id":"1",    "_version":4,    "result":"updated",    "_shards":{        "total":2,        "successful":2,        "failed":0    },    "created":false}{    "_index":"test@1555344000000_30",    "_type":"test",    "_id":"1",    "_version":4,    "found":true,    "_source":{        "title":"test4",        "timestamp":"1556305107154"    }}

可以看到第2条命令返回的title字段为test4,返回了修改之后的数据test4。

这时我们并没有使用refresh刷新技巧就查询到了最新的文档。

总结

修改数据、search数据:不一定会查询到最新的数据。

修改数据、refresh强制刷新、search数据:会查询到最新的数据。

修改数据、指定文档id查询数据:会查询到最新的数据。

往期推荐

《鹅厂老司机教你学习Innodb》

《腾讯数据库专家雷海林分享智能运维架构》

年中薅羊毛,可省18040元

云数据库MySQL年中疯狂折扣中,买MySQL高可用版送6个月数据迁移服务,1核1G内存100G SSD盘低至96.8元/月。免费数据管理DMC,双节点架构,自动容灾,最高可省18040元!点击左下角“阅读原文”立即参与~

↓↓点“阅读原文”享年中福利

好文和朋友一起看!

var first_sceen__time = (+new Date());if ("" == 1 && document.getElementById('js_content')) { document.getElementById('js_content').addEventListener("selectstart",function(e){ e.preventDefault(); }); } (function(){ if (navigator.userAgent.indexOf("WindowsWechat") != -1){ var link = document.createElement('link'); var head = document.getElementsByTagName('head')[0]; link.rel = 'stylesheet'; link.type = 'text/css'; link.href = "//res.wx.qq.com/mmbizwap/zh_CN/htmledition/style/page/appmsg_new/winwx45ba31.css"; head.appendChild(link); } })();

游成松

赞赏

长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

阅读原文

阅读

分享 在看

已同步到看一看

取消 发送

我知道了

朋友会在“发现-看一看”看到你“在看”的内容

确定

已同步到看一看写下你的想法

最多200字,当前共字 发送

已发送

朋友将在看一看看到

确定

写下你的想法...

取消

发布到看一看

确定

最多200字,当前共字

发送中

微信扫一扫 关注该公众号

微信扫一扫 使用小程序

即将打开""小程序

取消 打开

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-05-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯云数据库 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 索引更新及更新提交
  • 事务日志
  • 准实时读取
  • 总结
    • 朋友会在“发现-看一看”看到你“在看”的内容
      • 朋友将在看一看看到
        • 发布到看一看
        相关产品与服务
        Elasticsearch Service
        腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档