# Storm Solr 集成
針對 Apache Solr 的 Storm 和 Trident 集成. 該軟件包包括一個 bolt和 trident state,它們可以使 Storm topology 將 storm tuples 的內容索引到 Solr collections.
## Index Storm tuples 到 Solr collection 中
bolt 和 trident state 使用一個提供的 mappers(映射器)來構建一個 `SolrRequest` 對象, 負責對 Solr 進行更新調用,從而更新指定的 collection 的 index.
## 使用示例
在本節中,我們將提供一些關于如何構建 Storm 和 Trident topologies 來索引 Solr 的簡單代碼片段. 在隨后的章節中,我們詳細介紹了 Storm Solr 集成的兩個關鍵組件,`SolrUpdateBolt` 和 `Mappers`,`SolrFieldsMapper` 和`SolrJsonMapper`。
## Storm Bolt 與 JSON Mapper 和 Count Based Commit Strategy
```
new SolrUpdateBolt(solrConfig, solrMapper, solrCommitStgy)
// zkHostString for Solr 'gettingstarted' example
SolrConfig solrConfig = new SolrConfig("127.0.0.1:9983");
// JSON Mapper used to generate 'SolrRequest' requests to update the "gettingstarted" Solr collection with JSON content declared the tuple field with name "JSON"
SolrMapper solrMapper = new SolrJsonMapper.Builder("gettingstarted", "JSON").build();
// Acks every other five tuples. Setting to null acks every tuple
SolrCommitStrategy solrCommitStgy = new CountBasedCommit(5);
```
## Trident Topology 與 Fields Mapper
```
new SolrStateFactory(solrConfig, solrMapper);
// zkHostString for Solr 'gettingstarted' example
SolrConfig solrConfig = new SolrConfig("127.0.0.1:9983");
/* Solr Fields Mapper used to generate 'SolrRequest' requests to update the "gettingstarted" Solr collection. The Solr index is updated using the field values of the tuple fields that match static or dynamic fields declared in the schema object build using schemaBuilder */
SolrMapper solrMapper = new SolrFieldsMapper.Builder(schemaBuilder, "gettingstarted").build();
// builds the Schema object from the JSON representation of the schema as returned by the URL http://localhost:8983/solr/gettingstarted/schema/
SchemaBuilder schemaBuilder = new RestJsonSchemaBuilder("localhost", "8983", "gettingstarted")
```
## SolrUpdateBolt
`SolrUpdateBolt` 讓 tuples 直接流入到 Apache Solr 中. 該 Solr index 使用 `SolrRequest` 請求來更新. 該 `SolrUpdateBolt` 可以通過實現 `SolrConfig`, `SolrMapper` 和可選的 `SolrCommitStrategy` 方法來配置它.
使用 `SolrMapper` 實現中定義的策略從 tuples 中提取 stream 到 Solr 的數據.
`SolrRquest` 可以用來發送每個 tuple,也可以根據 `SolrCommitStrategy` 實現中定義的策略進行發送. 如果 `SolrCommitStrategy` 已經到位并且批處理中的一個元組失敗,則該 batch 不會被提交,并且該 bathc 中的所有 tuple 都標記為`Fail`,并重試. 另一方面,如果所有的 tuple 都成功,則 `SolrRequest` 被提交,所有 tuple 都被成功地 acked(確認).
`SolrConfig` 是包含 Solr 配置的 class,可用于 Storm Solr bolt. bolt 中需要的任何配置都應該放在這個 class 中.
## SolrMapper
`SorlMapper` 實現定義了從 tuple 中提取信息的策略. public method `toSolrRequest` 接收一個 tuple 或一組 tuple,并返回一個用于更新 Solr 索引的 `SolrRequest` 對象.
### SolrJsonMapper
`SolrJsonMapper` `創建一個 Solr 更新請求,該請求被發送到由 Solr 定義的作為 JSON 格式請求的 URL endpoint.
要創建一個 `SolrJsonMapper`,客戶端必須指定要更新的 collection 的名稱以及包含用于更新 Solr 索引的 JSON 對象的 tuple field(元組字段). 如果 tuple 不包含指定的字段,則在調用方法 `toSolrRequest` 時拋出 `SolrMapperException`. 如果該字段存在,則其值可以是 JSON 格式的內容的 String,或將被序列化為 JSON 的 Java 對象.
下面的代碼片段,說明如何創建一個 `SolrJsonMapper` `對象,以更新`getsstarted`Solr collection,并使用名稱為`JSON` 的 tuple 字段中聲明的 JSON 內容
```
SolrMapper solrMapper = new SolrJsonMapper.Builder("gettingstarted", "JSON").build();
```
### SolrFieldsMapper
`SolrFieldsMapper` 創建一個 Solr 更新請求,該請求被發送到處理 `SolrInputDocument` 對象的更新的 Solr URL endpoint.
要創建一個 `SolrFieldsMapper`,客戶端必須指定要更新的集合的名稱以及 `SolrSchemaBuilder`。 Solr 的 `Schema` 用于提取有關 Solr schema 字段和相應類型的信息. 該 metadata 用于從 tuples 中獲取信息. 只有匹配靜態或動態 Solr 字段的 tuple 字段才會添加到文檔中 與 schema 不匹配的 tuple 字段不添加到準備進行索引的 `SolrInputDocument` 中. 針對不匹配 schema 的 tuple 字段打印出 debug log message,因此不進行索引.
`SolrFieldsMapper` 支持多 value 的字段. 多 value 的 tuple 字段必須被 tokenized(分詞). 默認的 token(詞元)是 `|`. 可以通過調用作為 `SolrFieldsMapper.Builder` builder class 中的方法`org.apache.storm.solr.mapper.SolrFieldsMapper.Builder.setMultiValueFieldToken` 來指定任意的 token(詞元).
下面的代碼片段演示了如何去創建一個 `SolrFieldsMapper` 對象以更新 `gettingstarted` 的 Solr collection. 該多個 value 的字段使用 `%` 而不是默認的 `|` 來拆分每個 value. 要使用默認的 token 您可以省略對 `setMultiValueFieldToken` 方法的調用.
```
new SolrFieldsMapper.Builder(
new RestJsonSchemaBuilder("localhost", "8983", "gettingstarted"), "gettingstarted")
.setMultiValueFieldToken("%").build();
```
## 構建并且運行附帶的示例
為了能夠運行這些示例,您必須首先在 `storm-solr` 包中構建 `java` 代碼,然后生成具有所有依賴項的 `uber jar`.
## 構建 Storm Apache Solr 集成的代碼
`mvn clean install -f REPO_HOME/storm/external/storm-solr/pom.xml`
## 使用 Maven Shade 插件來構建 Uber Jar
添加以下配置到 `REPO_HOME/storm/external/storm-solr/pom.xml` 中:
```
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>org.apache.storm.solr.topology.SolrJsonTopology</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
```
通過運行命令以創建 uber jar:
`mvn package -f REPO_HOME/storm/external/storm-solr/pom.xml`
這將創建一個與以下模式匹配的名稱和位置的 uber jar 文件:
`REPO_HOME/storm/external/storm/target/storm-solr-0.11.0-SNAPSHOT.jar`
## 運行示例
復制文件 `REPO_HOME/storm/external/storm-solr/target/storm-solr-0.11.0-SNAPSHOT.jar` 到 `STORM_HOME/extlib`
**The code examples provided require that you first run the [Solr gettingstarted](http://lucene.apache.org/solr/quickstart.html) example**
### 運行 Storm Topology
```
STORM_HOME/bin/storm jar REPO_HOME/storm/external/storm-solr/target/storm-solr-0.11.0-SNAPSHOT-tests.jar org.apache.storm.solr.topology.SolrFieldsTopology
STORM_HOME/bin/storm jar REPO_HOME/storm/external/storm-solr/target/storm-solr-0.11.0-SNAPSHOT-tests.jar org.apache.storm.solr.topology.SolrJsonTopology
```
### 運行 Trident Topology
```
STORM_HOME/bin/storm jar REPO_HOME/storm/external/storm-solr/target/storm-solr-0.11.0-SNAPSHOT-tests.jar org.apache.storm.solr.trident.SolrFieldsTridentTopology
STORM_HOME/bin/storm jar REPO_HOME/storm/external/storm-solr/target/storm-solr-0.11.0-SNAPSHOT-tests.jar org.apache.storm.solr.trident.SolrJsonTridentTopology
```
### 驗證結果
上述的 Storm 和 Trident topologies 索引了 Solr `getsstarted` collect,其對象具有以下的 'id` 模式:
*id_fields_test_val* 用于 `SolrFieldsTopology` 和 `SolrFieldsTridentTopology`
*json_test_val* 用于 `SolrJsonTopology` 和 `SolrJsonTridentTopology`
查詢這些模式的 Solr,您將看到由 Storm Apache Solr 集成索引的值:
```
curl -X GET -H "Content-type:application/json" -H "Accept:application/json" http://localhost:8983/solr/gettingstarted_shard1_replica2/select?q=*id_fields_test_val*&wt=json&indent=true
curl -X GET -H "Content-type: application/json" -H "Accept: application/json" http://localhost:8983/solr/gettingstarted_shard1_replica2/select?q=*id_fields_test_val*&wt=json&indent=true
```
您還可以通過打開 Apache Solr UI 并在查詢頁面中的 `q` 文本框中粘貼 `id` 模式來查看結果
```
http://localhost:8983/solr/#/gettingstarted_shard1_replica2/query
```
- Storm 基礎
- 概念
- Scheduler(調度器)
- Configuration
- Guaranteeing Message Processing
- 守護進程容錯
- 命令行客戶端
- Storm UI REST API
- 理解 Storm Topology 的 Parallelism(并行度)
- FAQ
- Layers on Top of Storm
- Storm Trident
- Trident 教程
- Trident API 綜述
- Trident State
- Trident Spouts
- Trident RAS API
- Storm SQL
- Storm SQL 集成
- Storm SQL 示例
- Storm SQL 語言參考
- Storm SQL 內部實現
- Flux
- Storm 安裝和部署
- 設置Storm集群
- 本地模式
- 疑難解答
- 在生產集群上運行 Topology
- Maven
- 安全地運行 Apache Storm
- CGroup Enforcement
- Pacemaker
- 資源感知調度器 (Resource Aware Scheduler)
- 用于分析 Storm 的各種內部行為的 Metrics
- Windows 用戶指南
- Storm 中級
- 序列化
- 常見 Topology 模式
- Clojure DSL
- 使用沒有jvm的語言編輯storm
- Distributed RPC
- Transactional Topologies
- Hooks
- Storm Metrics
- Storm 狀態管理
- Windowing Support in Core Storm
- Joining Streams in Storm Core
- Storm Distributed Cache API
- Storm 調試
- 動態日志級別設置
- Storm Logs
- 動態員工分析
- 拓撲事件檢查器
- Storm 與外部系統, 以及其它庫的集成
- Storm Kafka Integration
- Storm Kafka 集成(0.10.x+)
- Storm HBase Integration
- Storm HDFS Integration
- Storm Hive 集成
- Storm Solr 集成
- Storm Cassandra 集成
- Storm JDBC 集成
- Storm JMS 集成
- Storm Redis 集成
- Azue Event Hubs 集成
- Storm Elasticsearch 集成
- Storm MQTT(Message Queuing Telemetry Transport, 消息隊列遙測傳輸) 集成
- Storm MongoDB 集成
- Storm OpenTSDB 集成
- Storm Kinesis 集成
- Storm Druid 集成
- Storm and Kestrel
- Container, Resource Management System Integration
- Storm 高級
- 針對 Storm 定義一個不是 JVM 的 DSL
- 多語言協議
- Storm 內部實現
- 翻譯進度