<type>本文档解释了“ Esindex”的用法和配置,这是Cassandra的基于Elasticsearch的辅助索引。
该插件需要已经配置的Elasticsearch(ES)群集。
该插件将安装在常规的Cassandra 4.0.x版本中,从http://cassandra.apache.org/下载。 Cassandra配置文件没有任何更改可以支持索引。对于不使用该索引的应用程序,Cassandra的行为保持不变。
一旦在Cassandra表上创建后,该索引就可以使用CQL在Cassandra上执行“全文搜索”弹性搜索查询,并从Cassandra Data中返回匹配行。此插件的使用不需要更改Cassandra源代码,我们已经使用以下方式实施了Cassandra的Elasticsearch索引:

经过测试的版本是Elasticsearch 5.x,6.x,7.x和Cassandra 4.0.x.但是,如果应用程序提供相应的映射和选项,则该插件还可以与不同的Elasticsearch版本(1.7、2.x 5.x,6.x,7.x)一起使用。其他版本的Apache Cassandra(例如1.x 2.x,3.x或4.1)不受支持,因为插件使用的辅助索引接口不同。其他Cassandra供应商未经测试,不支持Scylladb。
| 版本 | Elasticsearch 1.x | Elasticsearch 2.x | Elasticsearch 5.x | Elasticsearch 6.x | Elasticsearch 7.x |
|---|---|---|---|---|---|
| 卡桑德拉1.x | 不 | 不 | 不 | 不 | 不 |
| 卡桑德拉2.x | 不 | 不 | 不 | 不 | 不 |
| 卡桑德拉3.x | 不 | 不 | 不 | 不 | 不 |
| 卡桑德拉4.x | 有限的 | 有限的 | 有限的 | 是的 | 是的 |
该项目需要Maven并使用Java 8进行编译。要在项目的根源下构建插件:
MVN干净包装
这将在target/distribution/lib4cassandra中构建一个“全罐”
<dependency>
<groupId>com.genesyslab</groupId>
<artifactId>es-index</artifactId>
<version>9.2.000.00</version>
</dependency>
请参阅GitHub软件包
请参阅Maven存储库
将es-index-9.2.000.xx-jar-with-dependencies.jar置于卡桑德拉的lib文件夹中,例如所有卡桑德拉节点上的“/usr/usr/share/share/cassandra/lib”。启动或重新启动您的Cassandra节点。
由于缺乏测试,因此不支持带有聚类键的表。仅支持一个分区密钥,复合分区键应起作用,但不能进行广泛的测试。
EsIndex仅支持行级TTL,其中所有单元将同时到期,并且可以同时删除相应的ES文档。如果一排的单元格在不同时间到期,则在最后一个单元期到期时将删除相应的文档。如果使用不同的单元格TTL,则从sstables读取数据时,从搜索中返回的数据仍然是一致的,但是仍然可以使用ES查询使用过期数据找到行。
可以在同一表上创建多个索引,Esindex不会阻止这一点。但是,如果存在多个Esindex的行为可能不一致,则不支持这种配置。 CQLSH命令“描述表<ks.tablename>”可用于显示表上创建的索引,并在必要时放置它们。
为了简单起见,首先创建此密钥空间:
CREATE KEYSPACE genesys WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}
让我们以下表以一个例子:
CREATE TABLE genesys.emails (
id UUID PRIMARY KEY,
subject text,
body text,
userid int,
query text
);
您需要专用一个虚拟文本列以进行索引使用。本列绝不能接收数据。在此示例中, query列是虚拟列。
这是如何为示例表创建索引并将Eshost用于Elasticsearch:
CREATE CUSTOM INDEX ON genesys.emails(query)
USING 'com.genesyslab.webme.commons.index.EsSecondaryIndex'
WITH OPTIONS = {'unicast-hosts': 'eshost:9200'};
例如,如果您的Elasticsearch Server在localhost上收听,请用Localhost替换Eshost 。
CQL返回的错误非常有限,如果出现问题,例如您的Elasticsearch主机不可用,您会获得超时或其他类型的例外。您必须检查Cassandra日志以了解出了什么问题。
我们没有提供任何映射,因此我们依靠Elasticsearch动态映射,让我们插入一些数据:
INSERT INTO genesys.emails (id, subject, body, userid)
VALUES (904b88b2-9c61-4539-952e-c179a3805b22, 'Hello world', 'Cassandra is great, but it''s even better with EsIndex and Elasticsearch', 42);
如果您可以访问日志:
[o.e.c.m.MetaDataCreateIndexService] [node-1] [genesys_emails_index@] creating index, cause [api], templates [], shards [5]/[1], mappings []
[INFO ][o.e.c.m.MetaDataMappingService] [node-1] [genesys_emails_index@/waSGrPvkQvyQoUEiwqKN3w] create_mapping [emails]
现在,我们可以通过索引使用Elasticsearch搜索Cassandra,这是Lucene语法搜索:
select id, subject, body, userid, query from emails where query='body:cassan*';
id | subject | body | userid | query
--------------------------------------+-------------+-------------------------------------------------------------------------+--------+-------
904b88b2-9c61-4539-952e-c179a3805b22 | Hello world | Cassandra is great, but it's even better with EsIndex and Elasticsearch | 42 |
{
"_index": "genesys_emails_index@",
"_type": "emails",
"_id": "904b88b2-9c61-4539-952e-c179a3805b22",
"_score": 0.24257512,
"_source": {
"id": "904b88b2-9c61-4539-952e-c179a3805b22"
},
"took": 4,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 0.24257512
}
}
(1 rows)
(JSON格式化)
所有行都将使用CQL一致性包含从Sstables加载的Cassandra的数据。 “查询”列中的数据是Elasticsearch返回的元数据。
这是查询Elasticsearch的方法以检查生成的映射: GET http://eshost:9200/genesys_emails_index@/emails/_mapping?pretty
{
"genesys_emails_index@" : {
"mappings" : {
"emails" : {
"properties" : {
"IndexationDate" : {
"type" : " date "
},
"_cassandraTtl" : {
"type" : " long "
},
"body" : {
"type" : " text " ,
"fields" : {
"keyword" : {
"type" : " keyword " ,
"ignore_above" : 256
}
}
},
"id" : {
"type" : " text " ,
"fields" : {
"keyword" : {
"type" : " keyword " ,
"ignore_above" : 256
}
}
},
"subject" : {
"type" : " text " ,
"fields" : {
"keyword" : {
"type" : " keyword " ,
"ignore_above" : 256
}
}
},
"userid" : {
"type" : " text " ,
"fields" : {
"keyword" : {
"type" : " keyword " ,
"ignore_above" : 256
}
}
}
}
}
}
}
}Esindex插件添加了两个字段:
我们可以看到映射看起来不错,但是Elasticsearch并未注意到UserID是整数并添加了所有文本的字段[关键字]。
这是eLasticsearch中的数据的样子:
GET http://localhost:9200/genesys_emails_index@/emails/_search?pretty&q=body:cassandra
{
"took" : 2 ,
"timed_out" : false ,
"_shards" : {
"total" : 5 ,
"successful" : 5 ,
"skipped" : 0 ,
"failed" : 0
},
"hits" : {
"total" : 1 ,
"max_score" : 0.2876821 ,
"hits" : [
{
"_index" : " genesys_emails_index@ " ,
"_type" : " emails " ,
"_id" : " 904b88b2-9c61-4539-952e-c179a3805b22 " ,
"_score" : 0.2876821 ,
"_source" : {
"id" : " 904b88b2-9c61-4539-952e-c179a3805b22 " ,
"body" : " Cassandra is great, but it's even better with EsIndex and Elasticsearch " ,
"subject" : " Hello world " ,
"userid" : " 42 " ,
"IndexationDate" : " 2019-01-15T16:53:00.107Z " ,
"_cassandraTtl" : 2147483647
}
}
]
}
}让我们通过删除索引来修复映射: drop index genesys.emails_query_idx;这还将删除Elasticsearch索引和数据!
并通过适当的映射重新创建它:
CREATE CUSTOM INDEX ON genesys.emails(query)
USING 'com.genesyslab.webme.commons.index.EsSecondaryIndex'
WITH OPTIONS = {
'unicast-hosts': 'localhost:9200',
'mapping-emails': '
{
"emails":{
"date_detection":false,
"numeric_detection":false,
"properties":{
"id":{
"type":"keyword"
},
"userid":{
"type":"long"
},
"subject":{
"type":"text",
"fields":{
"keyword":{
"type":"keyword",
"ignore_above":256
}
}
},
"body":{
"type":"text"
},
"IndexationDate":{
"type":"date",
"format":"yyyy-MM-dd''T''HH:mm:ss.SSS''Z''"
},
"_cassandraTtl":{
"type":"long"
}
}
}
}
'};
这将创建一个新的索引将提供映射并重新指标卡桑德拉中的数据。
这是由此产生的ES映射:
{
"genesys_emails_index@" : {
"mappings" : {
"emails" : {
"date_detection" : false ,
"numeric_detection" : false ,
"properties" : {
"IndexationDate" : {
"type" : " date " ,
"format" : " yyyy-MM-dd'T'HH:mm:ss.SSS'Z' "
},
"_cassandraTtl" : {
"type" : " long "
},
"body" : {
"type" : " text "
},
"id" : {
"type" : " keyword "
},
"subject" : {
"type" : " text " ,
"fields" : {
"keyword" : {
"type" : " keyword " ,
"ignore_above" : 256
}
}
},
"userid" : {
"type" : " long "
}
}
}
}
}
}现在,正确定义了映射,我们可以搜索用户ID为一个数字。在此示例中,我们正在使用Elasticsearch查询DSL:
select id, subject, body, userid from genesys.emails
where query='{"query":{"range":{"userid":{"gte":10,"lte":50}}}}';
@ Row 1
---------+-------------------------------------------------------------------------
id | 904b88b2-9c61-4539-952e-c179a3805b22
subject | Hello world
body | Cassandra is great, but it's even better with EsIndex and Elasticsearch
userid | 42
在开始生产之前正确获取映射非常重要。重新索引一张大桌子将花费大量时间,并将对Cassandra和Elasticsearch造成重大负担。您需要检查Cassandra日志是否有ES映射中的错误。确保通过在提供给创建索引命令的JSON选项中加倍的JSON选项来逃脱单引号(')。
以下是与Elasticsearch索引配置有关的所有选项。关键名称可以使用连字符' - 'char或点。例如,两个名称都可以工作:
请注意,以下所有选项都是特定于Genesys实施的,而不是Elasticsearch本身。
如果找不到开玩笑类,则启用虚拟模式,并且没有其他情况。
仅支持多名分子,并且仅通过Cassandra八卦复制来复制数据。不同DC上的ES集群并不相同,绝对不要将其连接在一起,否则性能将受到影响。由于数据在表级别上复制,因此EsIndex将在每个DC中进行更新,并且本地ES群集也将更新。

为了支持Multi-DC,所有选项都可以由数据中心和RACK名称进行前缀,以使设置位置特定,例如:
为了为Elasticsearch提供Cassandra索引,每个节点必须在启动之前正确设置环境变量。必须将其设置在所有Cassandra主机上。
下面的示例提供了用户“弹性”和密码'示例'示例'的密码:(colon)字符。它可以直接在系统中作为环境变量进行,也可以在启动Cassandra的快捷方式中进行。
escredentials = Elastic:examplePassword一旦成功初始化了索引,它将在信息级别的Cassandra日志中编写“ Elasticsearch凭据”。一旦输出此消息,就可以清除环境变量。如果重新启动Cassandra,则必须在开始之前再次设置环境变量。凭据仅保存在内存中,并且在其他任何地方都没有保存。如果更改了用户和/或密码,则所有Cassandra节点都必须使用更新的环境变量值重新启动。
在索引选项集中
Unicast-hosts = https : //<host name>:9200
目前不可能将现有索引从HTTP迁移到HTTP,必须在创建Cassandra模式之前确定一个或另一个的使用。为了简化HTTPS部署,该索引将自动信任所有HTTPS证书。
与定义的Cassandra TTL相比,可以将数据保留在Elasticsearch的一边更长的时间。使用ES分析模式选项转动此模式。当启用选项时,ElasticIndex将跳过所有删除操作。
为了防止数据在ES方面增长过多,建议使用TTL换挡和强制降低设置。
创建索引时,您将提供索引选项,以及使用“使用选项” CQL命令的Elasticsearch索引选项。
索引选项应在索引创建中指定,这是一个示例
CREATE CUSTOM INDEX on genesys.email(query) using 'com.genesyslab.webme.commons.index.EsSecondaryIndex' WITH options =
{
'read-consistency-level':'QUORUM',
'insert-only':'false',
'index-properties': '{
"index.analysis.analyzer.dashless.tokenizer":"dash-ex",
"index.analysis.tokenizer.dash-ex.pattern":"[^\\w\\-]",
"index.analysis.tokenizer.dash-ex.type":"pattern"
}',
'mapping-email': '{
"email": {
"dynamic": "false",
"properties": {
"subject" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}',
'discard-nulls':'false',
'async-search':'true',
'async-write':'false'
};
您还可以使用环境变量或Java系统属性来设置或覆盖选项,以将选项与“ Genesys-es-”一起前缀。
首先使用“创建自定义索引”命令中提供的选项。可以使用“。”,“ ./conf/”,“ .././conf/”或“ ./ bin/”中的名为es-index.properties的文件在本地覆盖它们。 (可以使用-dgenesys-es-esi-file或-dgenesys.es.es.esi.file System属性更改
这是文件内容的示例:
insert-inly = true dost-nulls = false async-write = false
| 姓名 | 默认 | 描述 |
|---|---|---|
| 最大值 | 10000 | 从ES搜索到加载Cassandra行的结果数量。 |
| 读取一致性级别 | 一 | 用于搜索,此一致性级用于加载木薯行。 |
| 仅插入 | 错误的 | 默认情况下,Esindex将使用UPSERT操作。在插入中,仅将模式数据始终被覆盖。 |
| 异步 - 写 | 真的 | 在不检查正确执行的情况下,发送索引更新异步。这提供了更快的写作,但是如果不可用ES群集,数据可能会变得不一致,因为写入不会失败。默认是正确的。 |
| 部分 | 离开 | 关闭,小时,日,月,年,自定义自动索引细分由此设置控制。如果设置为一天,每天都会在别名下创建一个新的索引。请注意,每小时会自动删除空索引。注意:不建议使用小时设置,因为它将创建许多索引并可能会降低性能。建议此设置用于开发和测试目的。 |
| 段名 | 如果段=自定义此值将用于新的索引创建。 | |
| 映射 - <type> | {} | 对于每个辅助索引,表名为类型,例如映射visit = {json定义}。 |
| 单次主持人 | http:// localhost:9200 | 主机的逗号分开列表可以是host1,host2,host3或http:// host1,http:// host2,http:// http:// host3或http:// http:// host1:9200,http:// http:// host2:9200,http:9200,http:// http:// host3:9200。如果丢失了http和9200的协议或端口。可以使用https。 |
| 丢弃无效 | 真的 | 请勿将零值传递给ES索引,这意味着您将无法删除一个值。默认是正确的。 |
| 索引 - 企业 | {} | 传递以创建新索引的JSON字符串的属性可能包含令牌定义。 |
| json serializatizatization场 | {} | 昏迷的字符串定义,必须将字符串列索引为JSON字符串。非json可放养字符串将阻止在Cassandra插入。 |
| JSON-FLAT-SERIAMIAD FIELD | {} | 昏迷的字符串定义,必须将字符串列索引为类型安全的JSON文档。 Elasticsearch JSON映射不允许索引随着时间的推移会更改类型的值。例如{“键”:“ value”}不能变为{“ key”:{“ subkey”:“ value”}}在elasticsearch中,您将获得映射异常。这样的JSON-FLAT将是将字符串键和字符串数组作为值的JSON对象转换为JSON对象。 |
| 假的 | 错误的 | 完全禁用次要索引。请注意,如果找不到开玩笑类,则将自动放入虚拟模式。 |
| 验证 | 错误的 | 将搜索查询发送到ES进行验证,以提供有意义的语法错误,而不是Cassandra超时。 |
| 并发锁 | 真的 | 分区ID上的锁定索引执行。当同时处理同一分区的多个更新时,这会防止并发问题。 |
| 跳过循环 | 真的 | 当Cassandra节点启动时,它将重播提交日志,这些更新会被跳过以改善启动时间,因为它们已经应用于ES。 |
| 跳过非本地升级 | 真的 | 为了提高启用此设置的性能,只能在令牌范围的主复制品上执行索引更新。 |
| ES分析模式 | 错误的 | 禁用ES文档的删除(TTL或DELETE)。 |
| 类型的二角 | 没有任何 | 设置管道的类型列表。 |
| 管道 - <type> | 没有任何 | 该类型的管道定义。 |
| index.translog.duroby | 异步 | 创建索引时,我们使用async Commit模式来确保最佳性能,它是ES 1.7中的默认设置。自2.x以来,它的同步会导致严重的性能下降。 |
| 可用的重建 | 真的 | 创建新索引时,可以(或不)在部分索引上运行搜索。 |
| 截短的重建 | 错误的 | 重建前将ES索引截断。 |
| 吹扫期 | 60 | 每60分钟,所有空索引都会从别名中删除。 |
| 每个索引类型 | 真的 | 用表名称准备索引名称。在ES 5.X中,不可能在同一索引的不同类型的同一字段名称中拥有不同的映射。在ES 6.x中,将删除。 |
| 力降低 | 错误的 | 每分钟,“删除查询”请求都会发送到ES,以删除已过期_cassandrattl的文档。这是为了模拟在ES 5.x中删除的TTL功能。请注意,尽管Cassandra压实实际上会从ES中删除文档,但不能保证它何时发生。 |
| TTL换档 | 0 | 几秒钟内移动Cassandra TTL的时间。如果Cassandra的TTL为1H,而Shift为3600,则意味着ES中的文档将比Cassandra晚1H。 |
| 索引经理 | com.genesyslab.webme.commons.index.defaultIndexManager | 索引管理器类名。用于管理细分和到期功能。 |
| 细分尺寸 | 86400000 | 段的段时间框架以毫秒为单位。每个“细分大小”毫秒新索引将通过以下模板创建:<Alias_name> _index@<yyyymmdd'hhmmsss'z'> |
| 最大连接 | 2 | 每个ES节点的HTTP连接数量,默认为Apache HTTP池值,可以提高Cassandra索引的性能,但会增加ES的负载。 (WCC 9.0.000.15中的新产品) |
您应该在映射定义中关闭日期检测。
以下JSON:
{
"maps" : {
"key1" : " value " ,
"key2" : 42 ,
"keymap" : {
"sss1" : null ,
"sss2" : 42 ,
"sss0" : " ffff "
},
"plap" : " plop "
},
"string" : " string " ,
"int" : 42 ,
"plplpl" : [ 1 , 2 , 3 , 4 ]
}将转换为:
{
"maps" : [ " key1=value " , " key2=42 " , " keymap={sss1=null, sss2=42, sss0=ffff} " , " plap=plop " ],
"string" : [ " string " ],
"int" : [ " 42 " ],
"plplpl" : [ " 1 " , " 2 " , " 3 " , " 4 " ]
}可能的值:
<type>有关类型映射的详细信息,请参见Elasticsearch文档:http://www.elasticsearch.org/guide/en/elasticsearch/reference/reference/current/mapping.html
支持所有Cassandra列类型,数据将以字符串,数组或地图发送,具体取决于Cassandra类型。通过适当的映射,Elasticsearch然后将数据转换为相关类型。这将允许更好的搜索和报告。
| 卡桑德拉类型 | Elasticsearch建议映射 | 评论 |
|---|---|---|
| ASCII | 文本或关键字 | 请参阅文本类型的下一节 |
| bigint | 长的 | |
| 斑点 | 禁用 | 不可能索引二进制内容 |
| 布尔 | 布尔 | |
| 柜台 | 长的 | |
| 日期 | 日期 | |
| 十进制 | 双倍的 | |
| 双倍的 | 双倍的 | |
| 漂浮 | 双倍的 | |
| inet | 关键词 | ES IP未测试 |
| int | int | |
| 列表<type> | 与类型相同 | ES期望类型可以是单个值或数组 |
| 地图< typek , typev > | 目的 | 如果您的钥匙具有很多不同的值,请提防映射爆炸 |
| SET <type> | 与类型相同 | ES期望类型可以是单个值或数组 |
| 小网 | int | |
| 文本 | 文本或关键字 | 请参阅文本类型的下一节 |
| 时间 | 关键词 | |
| 时间戳 | “ type”:“ date”,“格式”:“ yyyy-mm-dd'hh:mm:ss.ssss'z'” | |
| timeuuid | 关键词 | |
| 微小 | int | |
| 元组<type1 type2,...> | 类型 | |
| UUID | 关键词 | |
| Varchar | 文本或关键字 | 请参阅文本类型的下一节 |
| VARINT | 长的 | |
| 用户定义的类型 | 目的 | 每个UDT字段将使用其名称和值映射 |
文本类型的映射
当将文本(ASCII或VARCHAR)列发送到ES时,将其作为原始文本发送以索引。但是,如果文本是适当的JSON,则可以将其作为JSON文档发送,以供ES索引。这允许索引/搜索文档而不是原始文本。
使用此类JSON映射允许使用“ columnName.key:value”搜索数据。
如果您的钥匙具有很多不同的值,请提防映射爆炸
JSON-Serializatized场(有关详细信息,请参见选项)
文本的内容作为JSON发送。在映射中,您可以分别定义每个文档字段。请注意,一旦字段被映射为类型,即通过静态映射或动态映射,提供不兼容的类型将导致Cassandra写入故障。
json-flat-serializatized场(有关详细信息和转换示例,请参见选项)
文本的内容也作为JSON发送,但是所有值都被迫将平面字符串阵列发送。这将限制搜索嵌套的JSON的能力,但是如果您无法控制值的JSON类型,则会更安全。
这是Cassandra指数的自定义实现。这引入了与Cassandra一致性模型相关的一些局限性。主要限制是由于Cassandra二级索引的性质,每个Cassandra节点仅包含其在Cassandra环内负责的数据,其辅助索引是同一件事,每个节点仅索引其本地数据。这意味着,在索引上进行查询时,查询将发送到所有节点,然后通过查询协调器汇总结果并返回给客户端。
使用EsIndex,这是不同的,因为索引搜索基于Elasticsearch,因此每个节点都能响应查询。这意味着查询必须仅发送到单个节点或结果将包含重复。这是通过将令牌强制到下面的CQL查询来实现的。
select * from emails where query='subject:12345' and token(id)=0;
令牌应该是跨节点传播查询的任何随机长度值。它必须在上面的示例中的行键上构建。
在上面的示例中,Elasticsearch查询是“主题:12345”。这是一个像查询一样的露西。有关更多详细信息,也可以执行DSL查询请参见Elasticsearch Query-DSL页面。
单个Elasticsearch索引将包含给定键空间的所有Cassandra表索引。对于每个索引,都使用专用的Elasticsearch类型。为了允许跨桌子聚合,该类型在查询中未执行。这意味着,如果您的查询可以匹配不同的类型,它将返回的ID超过预期。由于这些不匹配Cassandra行,您将不会获得更多的结果,但是如果限制返回结果的数量,也可能会得到更少的结果。
如果匹配的行计数很高,并且行很大,则搜索可能会以阅读超时结束。您只能请求PK用ES Metadata返回,然后使用CQL查询与代码并行加载行。
为了告诉索引返回PK
select * from emails where query='#options:load-rows=false#id:ab*';
重要的是要注意,返回的行是假的,并根据eLasicsearch查询的结果构建。这意味着返回的行可能不再存在:
Hen a搜索请求返回结果,第一行将在索引列中以## json字符串包含Elasticsearch元数据。例如,请参见:
cqlsh:ucs> select id,query from emails where query='id:00008RD9PrJMMmpr';
id | query
------------------+---------------------------------------------------------------------------------------------------------------------
00008RD9PrJMMmpr | {"took":5,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":7.89821}}
Esindex分割机制将单片弹性搜索索引分解为基于时间的索引序列。目的如下:
由于Elasticsearch 5.x TTL不再支持。但是,卡桑德拉(Cassandra)的正常压实和维修过程会自动删除墓碑数据,ElasticIndex将从Elasticsearch中删除数据。
EsIndex支持CQL跟踪,可以在节点上启用它,也可以使用CQLSH与以下命令:
追踪;
跟踪选择,然后您会从整个查询中获得所有参与节点的痕迹:
cqlsh:ucs> select * from "Contact" where "ESQuery"='AttributeValues.LastName:ab*' and token("Id")=0 limit 1;
Id | AttributeValues | AttributeValuesDate | Attributes| CreatedDate | ESQuery | ExpirationDate | MergeIds | ModifiedDate| PrimaryAttributes| Segment| TenantId
1001uiP2niJPJGBa | {"LastName":["IdentifyTest-aBEcKPnckHVP"],"EmailAddress":["IdentifyTest-HHzmNornOr"]} |{} | {'EmailAddress_IdentifyTest-HHzmNornOr': {Id: 'EmailAddress_IdentifyTest-HHzmNornOr', Name: 'EmailAddress', StrValue: 'IentifyTest-HHzmNornOr', Description: null, MimeType: null, IsPrimary: False}, 'LastName_IdentifyTest-aBEcKPnckHVP': {Id: 'LastName_IdentifyTest-aBEcKPnckHVP', Name: 'LastName', StrValue: 'IdentifyTest-aBEcKPnckHVP', Description: null, MimeType: null IsPrimary: False}} | 2018-10-30 02:05:06.960000+0000 | {"_index":"ucsperf2_contact_index@","_type":"Contact","_id":"1001uiP2niJPJGBa","_score":1.0,"_source":{"Id":"1001uiP2niJPJGBa"},"took":485,"timed_out":false,"_shards":{"total":5,"successful":5,failed":0},"hits":{"total":18188,"max_score":1.0}} | null | null | 2018-10-30 02:05:06.960000+0000 | {'EmailAddress': 'IdentifyTest-HHzmNornOr', 'LastName': 'IdentifyTest-aBEcKPnckHVP'} | not-applicable |1
(1 rows)
然后,您将从会话中获取跟踪信息:
跟踪会议:8ED07B60-180D-11E9-B832-33A7777983333
activity | timestamp | source | source_elapsed | client
-----------------------------------------------------------------------------------------------------------------------------------------+----------------------------+---------------+----------------+--------------
Execute CQL3 query | 2019-01-14 16:03:32.118000 | xxx.xx.47.82 | 0 | xxx.xx.40.11
RANGE_SLICE message received from /xxx.xx.47.82 [MessagingService-Incoming-/xxx.xx.47.82] | 2019-01-14 16:02:30.200000 | xxx.xx.47.49 | 34 | xxx.xx.40.11
Executing read on ucsperf2.Contact using index Contact_ESQuery_idx [ReadStage-1] | 2019-01-14 16:02:30.201000 | xxx.xx.47.49 | 411 | xxx.xx.40.11
ESI 00ebf964-b958-4e74-ab89-e0093a8ec188 Searching 'AttributeValues.LastName:ab*' [ReadStage-1] | 2019-01-14 16:02:30.201000 | xxx.xx.47.49 | 693 | xxx.xx.40.11
ESI 00ebf964-b958-4e74-ab89-e0093a8ec188 Found 10000 matching ES docs in 514ms [ReadStage-1] | 2019-01-14 16:02:30.716000 | xxx.xx.47.49 | 515336 | xxx.xx.40.11
ESI 00ebf964-b958-4e74-ab89-e0093a8ec188 StreamingPartitionIterator initialized [ReadStage-1] | 2019-01-14 16:02:30.717000 | xxx.xx.47.49 | 516911 | xxx.xx.40.11
reading data from /xxx.xx.47.100 [ReadStage-1] | 2019-01-14 16:02:30.717000 | xxx.xx.47.49 | 517121 | xxx.xx.40.11
speculating read retry on /xxx.xx.47.82 [ReadStage-1] | 2019-01-14 16:02:30.718000 | xxx.xx.47.49 | 517435 | xxx.xx.40.11
Executing single-partition query on Contact [ReadStage-2] | 2019-01-14 16:02:30.718000 | xxx.xx.47.49 | 517436 | xxx.xx.40.11
Sending READ message to /xxx.xx.47.100 [MessagingService-Outgoing-/xxx.xx.47.100-Small] | 2019-01-14 16:02:30.718000 | xxx.xx.47.49 | 517445 | xxx.xx.40.11
Sending READ message to /xxx.xx.47.82 [MessagingService-Outgoing-/xxx.xx.47.82-Small] | 2019-01-14 16:02:30.718000 | xxx.xx.47.49 | 517558 | xxx.xx.40.11
Acquiring sstable references [ReadStage-2] | 2019-01-14 16:02:30.718000 | xxx.xx.47.49 | 517866 | xxx.xx.40.11
Bloom filter allows skipping sstable 83 [ReadStage-2] | 2019-01-14 16:02:30.718000 | xxx.xx.47.49 | 517965 | xxx.xx.40.11
Partition index with 0 entries found for sstable 400 [ReadStage-2] | 2019-01-14 16:02:30.719000 | xxx.xx.47.49 | 518300 | xxx.xx.40.11
REQUEST_RESPONSE message received from /xxx.xx.47.82 [MessagingService-Incoming-/xxx.xx.47.82] | 2019-01-14 16:02:30.720000 | xxx.xx.47.49 | 519720 | xxx.xx.40.11
Processing response from /xxx.xx.47.82 [RequestResponseStage-4] | 2019-01-14 16:02:30.720000 | xxx.xx.47.49 | 519865 | xxx.xx.40.11
Bloom filter allows skipping sstable 765 [ReadStage-2] | 2019-01-14 16:02:30.723000 | xxx.xx.47.49 | 522352 | xxx.xx.40.11
Bloom filter allows skipping sstable 790 [ReadStage-2] | 2019-01-14 16:02:30.723000 | xxx.xx.47.49 | 522451 | xxx.xx.40.11
Bloom filter allows skipping sstable 819 [ReadStage-2] | 2019-01-14 16:02:30.723000 | xxx.xx.47.49 | 522516 | xxx.xx.40.11
Bloom filter allows skipping sstable 848 [ReadStage-2] | 2019-01-14 16:02:30.723000 | xxx.xx.47.49 | 522662 | xxx.xx.40.11
Bloom filter allows skipping sstable 861 [ReadStage-2] | 2019-01-14 16:02:30.723000 | xxx.xx.47.49 | 522741 | xxx.xx.40.11
Skipped 0/7 non-slice-intersecting sstables, included 0 due to tombstones [ReadStage-2] | 2019-01-14 16:02:30.723000 | xxx.xx.47.49 | 522855 | xxx.xx.40.11
Merged data from memtables and 1 sstables [ReadStage-2] | 2019-01-14 16:02:30.723001 | xxx.xx.47.49 | 523075 | xxx.xx.40.11
Read 1 live and 0 tombstone cells [ReadStage-2] | 2019-01-14 16:02:30.723001 | xxx.xx.47.49 | 523164 | xxx.xx.40.11
Read 1 live and 0 tombstone cells [ReadStage-1] | 2019-01-14 16:02:30.725000 | xxx.xx.47.49 | 524717 | xxx.xx.40.11
ESI 00ebf964-b958-4e74-ab89-e0093a8ec188 StreamingPartitionIterator closed [ReadStage-1] | 2019-01-14 16:02:30.725000 | xxx.xx.47.49 | 524805 | xxx.xx.40.11
Enqueuing response to /xxx.xx.47.82 [ReadStage-1] | 2019-01-14 16:02:30.725000 | xxx.xx.47.49 | 524872 | xxx.xx.40.11
Sending REQUEST_RESPONSE message to /xxx.xx.47.82 [MessagingService-Outgoing-/xxx.xx.47.82-Small] | 2019-01-14 16:02:30.725000 | xxx.xx.47.49 | 524971 | xxx.xx.40.11
REQUEST_RESPONSE message received from /xxx.xx.47.100 [MessagingService-Incoming-/xxx.xx.47.100] | 2019-01-14 16:02:30.729000 | xxx.xx.47.49 | 528222 | xxx.xx.40.11
Processing response from /xxx.xx.47.100 [RequestResponseStage-1] | 2019-01-14 16:02:30.729000 | xxx.xx.47.49 | 528364 | xxx.xx.40.11
Initiating read-repair [RequestResponseStage-1] | 2019-01-14 16:02:30.729000 | xxx.xx.47.49 | 528481 | xxx.xx.40.11
Parsing select * from "Contact" where "ESQuery"='AttributeValues.LastName:ab*' and token("Id")=0 limit 1; [Native-Transport-Requests-1] | 2019-01-14 16:03:32.119000 | xxx.xx.47.82 | 174 | xxx.xx.40.11
Preparing statement [Native-Transport-Requests-1] | 2019-01-14 16:03:32.119000 | xxx.xx.47.82 | 254 | xxx.xx.40.11
Index mean cardinalities are Contact_ESQuery_idx:-2109988917941223823. Scanning with Contact_ESQuery_idx. [Native-Transport-Requests-1] | 2019-01-14 16:03:32.119000 | xxx.xx.47.82 | 418 | xxx.xx.40.11
Computing ranges to query [Native-Transport-Requests-1] | 2019-01-14 16:03:32.121000 | xxx.xx.47.82 | 2480 | xxx.xx.40.11
Submitting range requests on 1 ranges with a concurrency of 1 (-4.6099044E15 rows per range expected) [Native-Transport-Requests-1] | 2019-01-14 16:03:32.121000 | xxx.xx.47.82 | 2568 | xxx.xx.40.11
Enqueuing request to /xxx.xx.47.49 [Native-Transport-Requests-1] | 2019-01-14 16:03:32.121000 | xxx.xx.47.82 | 2652 | xxx.xx.40.11
Submitted 1 concurrent range requests [Native-Transport-Requests-1] | 2019-01-14 16:03:32.121000 | xxx.xx.47.82 | 2708 | xxx.xx.40.11
Sending RANGE_SLICE message to /xxx.xx.47.49 [MessagingService-Outgoing-/xxx.xx.47.49-Small] | 2019-01-14 16:03:32.121000 | xxx.xx.47.82 | 2874 | xxx.xx.40.11
READ message received from /xxx.xx.47.49 [MessagingService-Incoming-/xxx.xx.47.49] | 2019-01-14 16:03:32.640000 | xxx.xx.47.100 | 29 | xxx.xx.40.11
READ message received from /xxx.xx.47.49 [MessagingService-Incoming-/xxx.xx.47.49] | 2019-01-14 16:03:32.640000 | xxx.xx.47.82 | 521263 | xxx.xx.40.11
Executing single-partition query on Contact [ReadStage-2] | 2019-01-14 16:03:32.640000 | xxx.xx.47.82 | 521468 | xxx.xx.40.11
Acquiring sstable references [ReadStage-2] | 2019-01-14 16:03:32.640000 | xxx.xx.47.82 | 521566 | xxx.xx.40.11
Partition index with 0 entries found for sstable 1187 [ReadStage-2] | 2019-01-14 16:03:32.640000 | xxx.xx.47.82 | 521775 | xxx.xx.40.11
Executing single-partition query on Contact [ReadStage-1] | 2019-01-14 16:03:32.641000 | xxx.xx.47.100 | 266 | xxx.xx.40.11
Bloom filter allows skipping sstable 1188 [ReadStage-2] | 2019-01-14 16:03:32.641000 | xxx.xx.47.82 | 522130 | xxx.xx.40.11
Acquiring sstable references [ReadStage-1] | 2019-01-14 16:03:32.641000 | xxx.xx.47.100 | 361 | xxx.xx.40.11
Bloom filter allows skipping sstable 1189 [ReadStage-2] | 2019-01-14 16:03:32.641000 | xxx.xx.47.82 | 522205 | xxx.xx.40.11
Bloom filter allows skipping sstable 1190 [ReadStage-2] | 2019-01-14 16:03:32.641000 | xxx.xx.47.82 | 522259 | xxx.xx.40.11
Skipped 0/5 non-slice-intersecting sstables, included 0 due to tombstones [ReadStage-2] | 2019-01-14 16:03:32.641001 | xxx.xx.47.82 | 522303 | xxx.xx.40.11
Bloom filter allows skipping sstable 1186 [ReadStage-2] | 2019-01-14 16:03:32.641001 | xxx.xx.47.82 | 522415 | xxx.xx.40.11
Merged data from memtables and 1 sstables [ReadStage-2] | 2019-01-14 16:03:32.641001 | xxx.xx.47.82 | 522540 | xxx.xx.40.11
Read 1 live and 0 tombstone cells [ReadStage-2] | 2019-01-14 16:03:32.641001 | xxx.xx.47.82 | 522679 | xxx.xx.40.11
Enqueuing response to /xxx.xx.47.49 [ReadStage-2] | 2019-01-14 16:03:32.641001 | xxx.xx.47.82 | 522734 | xxx.xx.40.11
Sending REQUEST_RESPONSE message to /xxx.xx.47.49 [MessagingService-Outgoing-/xxx.xx.47.49-Small] | 2019-01-14 16:03:32.641001 | xxx.xx.47.82 | 522863 | xxx.xx.40.11
Partition index with 0 entries found for sstable 1208 [ReadStage-1] | 2019-01-14 16:03:32.644000 | xxx.xx.47.100 | 3756 | xxx.xx.40.11
REQUEST_RESPONSE message received from /xxx.xx.47.49 [MessagingService-Incoming-/xxx.xx.47.49] | 2019-01-14 16:03:32.647000 | xxx.xx.47.82 | 528443 | xxx.xx.40.11
Processing response from /xxx.xx.47.49 [RequestResponseStage-2] | 2019-01-14 16:03:32.647000 | xxx.xx.47.82 | 528516 | xxx.xx.40.11
Bloom filter allows skipping sstable 1209 [ReadStage-1] | 2019-01-14 16:03:32.649000 | xxx.xx.47.100 | 9090 | xxx.xx.40.11
Bloom filter allows skipping sstable 1210 [ReadStage-1] | 2019-01-14 16:03:32.649000 | xxx.xx.47.100 | 9162 | xxx.xx.40.11
Bloom filter allows skipping sstable 1211 [ReadStage-1] | 2019-01-14 16:03:32.649000 | xxx.xx.47.100 | 9187 | xxx.xx.40.11
Skipped 0/5 non-slice-intersecting sstables, included 0 due to tombstones [ReadStage-1] | 2019-01-14 16:03:32.650000 | xxx.xx.47.100 | 9237 | xxx.xx.40.11
Bloom filter allows skipping sstable 1207 [ReadStage-1] | 2019-01-14 16:03:32.650000 | xxx.xx.47.100 | 9335 | xxx.xx.40.11
Merged data from memtables and 1 sstables [ReadStage-1] | 2019-01-14 16:03:32.650000 | xxx.xx.47.100 | 9571 | xxx.xx.40.11
Read 1 live and 0 tombstone cells [ReadStage-1] | 2019-01-14 16:03:32.650000 | xxx.xx.47.100 | 9734 | xxx.xx.40.11
Enqueuing response to /xxx.xx.47.49 [ReadStage-1] | 2019-01-14 16:03:32.650000 | xxx.xx.47.100 | 9842 | xxx.xx.40.11
Sending REQUEST_RESPONSE message to /xxx.xx.47.49 [MessagingService-Outgoing-/xxx.xx.47.49-Small] | 2019-01-14 16:03:32.650000 | xxx.xx.47.100 | 10116 | xxx.xx.40.11
Request complete | 2019-01-14 16:03:32.646708 | xxx.xx.47.82 | 528708 | xxx.xx.40.11
ESI开头的所有活动都是来自Esindex的活动:
* ESI <id> Searching 'AttributeValues.LastName:ab*': The query have been received and decoded by the ESIndex, it is now sent to ElasticSearch
* ESI <id> Found 10000 matching ES docs in 514ms: The query to ElasticSearch has found 10000 results
* ESI <id> StreamingPartitionIterator initialized: Streaming partition iterator have been provided with all Ids found, and starts reading rows
* ESI <id> StreamingPartitionIterator closed: Client is done reading rows (limit was 1)
跟踪更新/插入/删除
cqlsh:ucs> update "Contact" set "CreatedDate"='2017-04-01T11:21:59.001+0000' where "Id"='1001uiP2niJPJGBa';
跟踪会议:F76E4AC0-180E-11E9-B832-33A7777983333
activity | timestamp | source | source_elapsed | client
----------------------------------------------------------------------------------------------------------------------------------------+----------------------------+---------------+----------------+--------------
Execute CQL3 query | 2019-01-14 16:13:37.132000 | xxx.xx.47.82 | 0 | xxx.xx.40.11
MUTATION message received from /xxx.xx.47.82 [MessagingService-Incoming-/xxx.xx.47.82] | 2019-01-14 16:12:35.210000 | xxx.xx.47.49 | 22 | xxx.xx.40.11
Appending to commitlog [MutationStage-1] | 2019-01-14 16:12:35.210000 | xxx.xx.47.49 | 354 | xxx.xx.40.11
Adding to Contact memtable [MutationStage-1] | 2019-01-14 16:12:35.210000 | xxx.xx.47.49 | 465 | xxx.xx.40.11
Enqueuing response to /xxx.xx.47.82 [MutationStage-1] | 2019-01-14 16:12:35.212000 | xxx.xx.47.49 | 2356 | xxx.xx.40.11
Sending REQUEST_RESPONSE message to /xxx.xx.47.82 [MessagingService-Outgoing-/xxx.xx.47.82-Small] | 2019-01-14 16:12:35.212000 | xxx.xx.47.49 | 2548 | xxx.xx.40.11
Parsing update "Contact" set "CreatedDate"='2017-04-01T11:21:59.001+0000' where "Id"='1001uiP2niJPJGBa'; [Native-Transport-Requests-1] | 2019-01-14 16:13:37.132000 | xxx.xx.47.82 | 146 | xxx.xx.40.11
Preparing statement [Native-Transport-Requests-1] | 2019-01-14 16:13:37.132000 | xxx.xx.47.82 | 213 | xxx.xx.40.11
Determining replicas for mutation [Native-Transport-Requests-1] | 2019-01-14 16:13:37.133000 | xxx.xx.47.82 | 1895 | xxx.xx.40.11
Appending to commitlog [MutationStage-2] | 2019-01-14 16:13:37.134000 | xxx.xx.47.82 | 2042 | xxx.xx.40.11
Adding to Contact memtable [MutationStage-2] | 2019-01-14 16:13:37.134000 | xxx.xx.47.82 | 2149 | xxx.xx.40.11
Sending MUTATION message to /xxx.xx.47.100 [MessagingService-Outgoing-/xxx.xx.47.100-Small] | 2019-01-14 16:13:37.134000 | xxx.xx.47.82 | 2186 | xxx.xx.40.11
Sending MUTATION message to /xxx.xx.47.49 [MessagingService-Outgoing-/xxx.xx.47.49-Small] | 2019-01-14 16:13:37.134000 | xxx.xx.47.82 | 2232 | xxx.xx.40.11
MUTATION message received from /xxx.xx.47.82 [MessagingService-Incoming-/xxx.xx.47.82] | 2019-01-14 16:13:37.136000 | xxx.xx.47.100 | 28 | xxx.xx.40.11
Appending to commitlog [MutationStage-1] | 2019-01-14 16:13:37.136000 | xxx.xx.47.100 | 390 | xxx.xx.40.11
Adding to Contact memtable [MutationStage-1] | 2019-01-14 16:13:37.136000 | xxx.xx.47.100 | 471 | xxx.xx.40.11
ESI decoding row 31303031756950326e694a504a474261 [MutationStage-1] | 2019-01-14 16:13:37.137000 | xxx.xx.47.100 | 579 | xxx.xx.40.11
REQUEST_RESPONSE message received from /xxx.xx.47.49 [MessagingService-Incoming-/xxx.xx.47.49] | 2019-01-14 16:13:37.137000 | xxx.xx.47.82 | 5160 | xxx.xx.40.11
ESI writing 31303031756950326e694a504a474261 to ES index [MutationStage-1] | 2019-01-14 16:13:37.137000 | xxx.xx.47.100 | 664 | xxx.xx.40.11
Processing response from /xxx.xx.47.49 [RequestResponseStage-4] | 2019-01-14 16:13:37.137000 | xxx.xx.47.82 | 5280 | xxx.xx.40.11
ESI index 31303031756950326e694a504a474261 done [MutationStage-1] | 2019-01-14 16:13:37.160000 | xxx.xx.47.100 | 23878 | xxx.xx.40.11
REQUEST_RESPONSE message received from /xxx.xx.47.100 [MessagingService-Incoming-/xxx.xx.47.100] | 2019-01-14 16:13:37.160000 | xxx.xx.47.82 | 28445 | xxx.xx.40.11
Processing response from /xxx.xx.47.100 [RequestResponseStage-2] | 2019-01-14 16:13:37.160000 | xxx.xx.47.82 | 28549 | xxx.xx.40.11
Enqueuing response to /xxx.xx.47.82 [MutationStage-1] | 2019-01-14 16:13:37.162000 | xxx.xx.47.100 | 25614 | xxx.xx.40.11
Sending REQUEST_RESPONSE message to /xxx.xx.47.82 [MessagingService-Outgoing-/xxx.xx.47.82-Small] | 2019-01-14 16:13:37.162000 | xxx.xx.47.100 | 25793 | xxx.xx.40.11
Request complete | 2019-01-14 16:13:37.814048 | xxx.xx.47.82 | 682048 | xxx.xx.40.11
ESI开头的所有活动都是来自Esindex的活动:
* ESI decoding row <rowId>: update request have been received by the ESIndex, row is being converted to JSON
* ESI writing <rowId> to ES index: update is being sent to ElasticSearch
* ESI index <rowId> done: ElasticSearch acknowledged the update
这是搜索时发生的情况的一个示例:

这是同步写的一个示例(如果ES失败,Cassandra操作将失败):

这是异步写的一个示例:

这是异步写的一个示例,如果ES失败,Cassandra操作将不会失败:
