<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操作將不會失敗:
