原因
數據存儲在MYSQ庫中,數據基本維持不變,但數據量又較大(幾千萬)放在MYSQL中查詢效率上較慢,尋求一種簡單有效的方式提升查詢效率,MYSQL並不擅長大規模數據量下的數據查詢。前端
技術方案
考慮後期一樣會使用到es,這次直接結合spring-boot框架造成一個獨立服務,並不涉及UI展示內容,(ES版本2.4.5,5.0+版本的話就不能再使用spring data elasticsearch)技術組合以下:java
Spring Boot+ Spring-data-elasticsearch + Elasticsearchmysql
結合elasticsearch-jdbc插件,全量將數據一次性導入es中,後期不涉及數據變動。git
es安裝
測試期間單機安裝,官網下載對應版本,因爲筆者工做環境基於JDK7,因此下載5.0如下版本,5.0+均依賴Java8,同時使用到elasticsearch-jdbc插件,一併下載安裝完成。程序員
走過的大彎路
直接使用elasticsearch-jdbc工具,編寫腳本文件,抽取數據到es中,腳本樣例以下:github
-
#!/bin/sh
web -
-
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
spring -
bin=${DIR}/../bin
sql -
lib=${DIR}/../lib
緩存 -
-
echo '
-
{
-
"type": "jdbc",
-
"jdbc": {
-
"elasticsearch.autodiscover": true,
-
"url": "jdbc:mysql://192.168.1.3:3306/test",
-
"user": "root",
-
"password": "root",
-
"sql": "SELECT * from tb_name1",
-
"elasticsearch": {
-
"host": "192.168.1.1",
-
"port": 9300
-
},
-
"index": "my-index",
-
"type": "my-type"
-
}
-
}
-
' | java \
-
-cp "${lib}/*" \
-
-Dlog4j.configurationFile=${bin}/log4j2.xml \
-
org.xbib.tools.Runner \
-
org.xbib.tools.JDBCImporter
數據導入成功後,可以使用head插件直接查看到。使用基本查詢測試,查詢條件是name=測試&num=100,使用精確匹配term語句,查詢數據未果,實際使用num=100獨立查詢時,有相關數據。
問題跟蹤解決
致使此現象的緣由在於中文分詞的問題,使用elasticsearch-jdbc腳本中並未處理列的mapping類型。(中間作過一次嘗試,在腳本中定義對應的type_mapping,但並未成功,有興趣的朋友可再作嘗試)。
注:es與ik分詞插件結合,版本匹配須要特別關注,但本案例並不涉及
結合此案例,查詢時並不須要分詞,而是精確匹配,但es默認狀況下是指定string類型的分詞,因此在index建立以前咱們須要手動指定相關列不須要分詞:not_analyzed,形如:
-
CURL -XPOST http://192.168.1.105:9200/my-index -d {
-
-
{
-
"mappings": {
-
"my-type": {
-
"properties": {
-
"name": {
-
"type": "string",
-
"index": "not_analyzed"
-
},
-
"num": {
-
"type": "string",
-
"index": "not_analyzed"
-
}
-
}
-
}
-
}
-
}
建立索引成功後,再使用elasticsearch-jdbc的腳本導入數據,相關數據列不會再使用分詞分析,再使用term組合精確查詢時,就能夠查詢相關數據來。
SpringBoot應用
pom.xml關鍵配置
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-web</artifactId>
-
<exclusions>
-
<exclusion>
-
<artifactId>log4j-over-slf4j</artifactId>
-
<groupId>org.slf4j</groupId>
-
</exclusion>
-
</exclusions>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter</artifactId>
-
<exclusions>
-
<exclusion>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-logging</artifactId>
-
</exclusion>
-
</exclusions>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-test</artifactId>
-
<scope>test</scope>
-
</dependency>
-
<dependency>
-
<groupId>org.springframework.boot</groupId>
-
<artifactId>spring-boot-starter-log4j</artifactId>
-
<version>1.3.1.RELEASE</version>
-
</dependency>
與elasticsearch交互實體
-
@Document(indexName = "my-index", type = "my-type", shards = 5, replicas = 1, indexStoreType = "fs", refreshInterval = "-1")
-
public class DataBean {
-
-
/**
-
* code:名稱
-
*
-
* @since JDK 1.6
-
*/
-
public String name;
-
-
/**
-
* msg:編號
-
*
-
* @since JDK 1.6
-
*/
-
public String num;
-
-
}
與es交互接口類,返回數據的惟一_id值,若查得數據表示命中數據,若爲空並未數據不存在
-
public interface DataBeanRepository extends ElasticsearchRepository<DataBean, Long> {
-
//案例中並未使用,但能夠用
-
public List<BlackGreyData> findByNameAndNum(String name, String num);
-
}
下面是業務處理層,採用BoolQueryBuilder構建查詢條件,也便可基於DSL模塊查詢數據,還能夠採用Criteria查詢。
-
@Autowired
-
DataBeanRepository repository;
-
-
@Override
-
public List<DataBean> query(String name, String num, String type) {
-
//採用過濾器的形式,提升查詢效率
-
BoolQueryBuilder builder = QueryBuilders.boolQuery();
-
builder.must(QueryBuilders.termQuery("name", name)).must(QueryBuilders.termQuery("num", num));
-
Iterable<DataBean> lists = repository.search(builder);
-
-
List<DataBean> datas = new ArrayList<>();
-
for (DataBean dataBean : lists) {
-
datas.add(dataBean);
-
logger.info("---------------------->>>Request result = 【" + dataBean + "】");
-
}
-
return datas;
-
}
其它再編寫對應的請求響應邏輯,便可完成簡單服務的完成。
測試結果
GPS數據量5000W+,精確匹配查詢出來50條數據,耗時700ms左右,結果查詢緩存機制,基本能夠穩定在300ms左右。這也是在單節點,未做任何優化的狀況的結果。
源碼地址
https://github.com/backkoms/spring-boot-elasticsearch
擴展閱讀:
歪脖貳點零 ∣ 認知升級· 終身學習
程序員,除了編碼,生活還應該有沉澱!
長按,識別二維碼,加關注