本文內容
- 背景
- ES集群中第一個master節點
- ES slave節點
遷移到:http://www.bdata-cap.com/newsinfo/1712679.html
本文總結 Elasticsearch(以下簡稱ES)搭建集群的經驗。以 Elasticsearch-rtf-2.2.1 版本為例。
我搭過三個集群:研究ELK時搭了一個;測試環境搭了一個;生產環境搭了一個。回想起來,搭建這三個集群時遇到的問題都不一樣(我這么說,主要針對集群中節點發現,以及master問題,而不是es啟動不起來或報錯等問題)~
- 研究ELK時,搭建ES集群倒是很順利,原因很簡單,先從一台機器開始的;
- 可是測試環境搭建集群時,遭遇新加入節點一直不能發現 master 節點,或是集群節點出現都選舉自己為 master 這兩個情況,因為,節點都是陸續啟動的,配置不當,是會出問題;
- 等到在生產環境搭建集群時,遭遇無法選舉出 master 節點的情況。ES head 和 kopf 兩個插件都不可用,因為,既然集群沒有選舉出 master 節點,顯然,整個集群是用不了的。而前面的情況,head 和 kopf 插件還是能用的,但能用,意義也不大~
總結起來,搭建集群,應該注意兩個問題。首先,當然是 Elasticsearch.yml 配置是否正確;再就是你的操作方式。比如節點啟動步驟等。
因為,如果搭建一個集群,那么必須保證集群有一個 master 節點,一般來說,第一個啟動的節點,一定是 master。然后,分別啟動其他節點,這些節點就會找到 master 節點,而 master 節點,也會發現這些節點。
- 因此,配置集群中的第一個master節點,務必簡單(簡單到什么程度,后面再說),先啟動它,它會立刻成為 master 節點。之后,再配置其他節點,最好直接告訴它們,可能的 master 節點是什么,然后啟動他們,它們就會發現 master,而 master 節點,也會發現新加入的節點。
- 否則,如果第一個啟動的節點,配置過於復雜(條件苛刻),造成它不能成為 master 節點,那么,整個集群會失敗。
稍后,你再配置節點時,可以采用更高級、復雜點的配置,就不會有什么問題了~
所以,我才強調,ES 集群中第一個 master 節點的配置務必簡單,以后再調整。
背景
假設,我們想搭建這樣一個名為 myfirstcluster 的ES集群,它有兩個節點:
節點 | 主機名 | 是否為 master |
192.168.1.2 | es-01 | 是 |
192.168.1.3 | es-02 | 否 |
ES集群中第一個master節點
最簡單的 ES master 節點配置如下。該配置文件,是一個完整的 ES 配置文件,所以很長。我順便翻譯成了中文。
1: # ======================== Elasticsearch Configuration =========================
2: #
3: # 注意: Elasticsearch 大多數設置都有默認值.
4: # 在你着手調整和優化配置之前,確保你明白你期望什么,得到什么結果
5: #
6: # 配置一個節點的主要方式就是通過該文件. 該模板列出了大多數重要的設置.
7: #
8: # 更多配置選項參見如下鏈接:
9: # <http://www.elastic.co/guide/en/elasticsearch/reference/current/setup-configuration.html>
10: #
11: # ---------------------------------- 集群 -----------------------------------
12: #
13: # 集群名稱:
14: #
15: cluster.name: mycluster
16: #
17: # ------------------------------------ 節點 ------------------------------------
18: #
19: # 節點名稱:
20: #
21: node.name: es-01
22: node.master: true
23: node.data: true
24: #
25: # 為節點添加自定義屬性,如機架:
26: #
27: # node.rack: r1
28: #
29: # ----------------------------------- 路徑 ------------------------------------
30: #
31: # 存放數據的目錄 (多個目錄用逗號分隔):
32: #
33: # path.data: /path/to/data
34: #
35: # 日志文件目錄:
36: #
37: # path.logs: /path/to/logs
38: #
39: # ----------------------------------- 內存 -----------------------------------
40: #
41: # 啟動時鎖定內存:
42: #
43: # bootstrap.mlockall: true
44: #
45: # 確保設置了 `ES_HEAP_SIZE` 環境變量, 大小為系統內存的一半,
46: # 該值為線程可以使用的最大內存
47: #
48: # 當系統正在交換內存時, Elasticsearch 執行性能會很差.
49: #
50: # ---------------------------------- 網絡 -----------------------------------
51: #
52: # 設置綁定地址到指定IP (IPv4 or IPv6):
53: #
54: network.host: 192.168.1.2
55: #
56: # 設置自定義 HTTP 端口:
57: http.port: 9200
58: # 集群內部通信端口:
59: tcp.port: 9300
60: #
61: # 更多信息, 參見如下鏈接:
62: # <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-network.html>
63: #
64: # --------------------------------- 節點發現 ----------------------------------
65: #
66: # 當新節點加入時,傳遞一個主機的初始化列表以完成節點發現:
67: # 默認主機列表為 ["127.0.0.1", "[::1]"]
68: #
69: discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300"]
70: #
71: # 通過配置大多數節點阻止腦裂現象 (數量: 節點總數量 / 2 + 1):
72: #
73: # discovery.zen.minimum_master_nodes: 2
74: #
75: # 更多信息, 參見如下鏈接:
76: # <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-discovery.html>
77: #
78: # ---------------------------------- 網關 -----------------------------------
79: #
80: # 當整個集群重新啟動后, 只有 N 個節點啟動了, 集群才會恢復,否則將阻塞:
81: #
82: # gateway.recover_after_nodes: 2
83: #
84: # 更多信息, 參見如下鏈接:
85: # <http://www.elastic.co/guide/en/elasticsearch/reference/current/modules-gateway.html>
86: #
87: # ---------------------------------- 其他 -----------------------------------
88: #
89: # 禁止在一個系統上啟動多個節點:
90: #
91: # node.max_local_storage_nodes: 1
92: #
93: # 當刪除 index 是必需顯式名稱:
94: #
95: # action.destructive_requires_name: true
96:
97: index:
98: analysis:
99: tokenizer:
100: my_pinyin:
101: type: pinyin
102: first_letter: prefix
103: padding_char: ''
104: pinyin_first_letter:
105: type: pinyin
106: first_letter: only
107: mmseg_maxword:
108: type: mmseg
109: seg_type: max_word
110: mmseg_complex:
111: type: mmseg
112: seg_type: complex
113: mmseg_simple:
114: type: mmseg
115: seg_type: simple
116: semicolon_spliter:
117: type: pattern
118: pattern: ";"
119: pct_spliter:
120: type: pattern
121: pattern: "[%]+"
122: ngram_1_to_2:
123: type: nGram
124: min_gram: 1
125: max_gram: 2
126: ngram_1_to_3:
127: type: nGram
128: min_gram: 1
129: max_gram: 3
130: filter:
131: ngram_min_3:
132: max_gram: 10
133: min_gram: 3
134: type: nGram
135: ngram_min_2:
136: max_gram: 10
137: min_gram: 2
138: type: nGram
139: ngram_min_1:
140: max_gram: 10
141: min_gram: 1
142: type: nGram
143: min2_length:
144: min: 2
145: max: 4
146: type: length
147: min3_length:
148: min: 3
149: max: 4
150: type: length
151: pinyin_first_letter:
152: type: pinyin
153: first_letter: only
154: analyzer:
155: lowercase_keyword:
156: type: custom
157: filter:
158: - lowercase
159: tokenizer: standard
160: lowercase_keyword_ngram_min_size1:
161: type: custom
162: filter:
163: - lowercase
164: - stop
165: - trim
166: - unique
167: tokenizer: nGram
168: lowercase_keyword_ngram_min_size2:
169: type: custom
170: filter:
171: - lowercase
172: - min2_length
173: - stop
174: - trim
175: - unique
176: tokenizer: nGram
177: lowercase_keyword_ngram_min_size3:
178: type: custom
179: filter:
180: - lowercase
181: - min3_length
182: - stop
183: - trim
184: - unique
185: tokenizer: ngram_1_to_3
186: lowercase_keyword_ngram:
187: type: custom
188: filter:
189: - lowercase
190: - stop
191: - trim
192: - unique
193: tokenizer: ngram_1_to_3
194: lowercase_keyword_without_standard:
195: type: custom
196: filter:
197: - lowercase
198: tokenizer: keyword
199: lowercase_whitespace:
200: type: custom
201: filter:
202: - lowercase
203: tokenizer: whitespace
204: ik:
205: alias:
206: - ik_analyzer
207: type: ik
208: ik_max_word:
209: type: ik
210: use_smart: true
211: ik_smart:
212: type: ik
213: use_smart: true
214: mmseg:
215: alias:
216: - mmseg_analyzer
217: type: mmseg
218: mmseg_maxword:
219: type: custom
220: filter:
221: - lowercase
222: tokenizer: mmseg_maxword
223: mmseg_complex:
224: type: custom
225: filter:
226: - lowercase
227: tokenizer: mmseg_complex
228: mmseg_simple:
229: type: custom
230: filter:
231: - lowercase
232: tokenizer: mmseg_simple
233: comma_spliter:
234: type: pattern
235: pattern: "[,|\\s]+"
236: pct_spliter:
237: type: pattern
238: pattern: "[%]+"
239: custom_snowball_analyzer:
240: type: snowball
241: language: English
242: simple_english_analyzer:
243: type: custom
244: tokenizer: whitespace
245: filter:
246: - standard
247: - lowercase
248: - snowball
249: edge_ngram:
250: type: custom
251: tokenizer: edgeNGram
252: filter:
253: - lowercase
254: pinyin_ngram_analyzer:
255: type: custom
256: tokenizer: my_pinyin
257: filter:
258: - lowercase
259: - nGram
260: - trim
261: - unique
262: pinyin_first_letter_analyzer:
263: type: custom
264: tokenizer: pinyin_first_letter
265: filter:
266: - standard
267: - lowercase
268: pinyin_first_letter_keyword_analyzer:
269: alias:
270: - pinyin_first_letter_analyzer_keyword
271: type: custom
272: tokenizer: keyword
273: filter:
274: - pinyin_first_letter
275: - lowercase
276: path_analyzer: #used for tokenize :/something/something/else
277: type: custom
278: tokenizer: path_hierarchy
279:
280: #index.analysis.analyzer.default.type: mmseg
281: index.analysis.analyzer.default.type: ik
282:
283: # rtf.filter.redis.host: 127.0.0.1
284: # rtf.filter.redis.port: 6379
說明:
- 第15行,指定集群名稱 myfirstcluster;
- 第21行,指定節點名稱,最好寫主機名;
- 第22和23行,指定該是否可能為master節點,以及是否為數據節點。ES的所說master節點,其實弱化了很多,僅僅就是為了節點發現和選舉master節點而已,它甚至都可以不用來保存數據。
因此,看你的規划,完全可以讓一個 master 節點,不保存任何數據;
- 第54行,指定節點IP地址,192.168.1.2;
- 第57行,指定HTTP端口,比如,head、kopf插件等插件,都使用該端口。事實上,你可以指定從 92開頭的任何端口;
- 第59行,指定集群內部通信的端口,比如,節點發現都使用該端口。事實上,你可以指定93開頭的任何端口,該行也可以寫成“transport.tcp.port: 9300”;
這7行配置,在我看來,針對集群中第一個master節點,必須配置正確的。其他配置,可以暫時不用。
其中,第57行和第59行,實際上,一台物理機,是可以運行多個 ES,只需要指定不同的配置文件即可。
- 第69行,指定節點初始化列表,因為該節點是集群第一台機器,並且要當 master,所以寫”127.0.0.1:9300”,端口號,就是你在第59行指定的端口。相關資料顯示,也可以不指定端口,那是不是會93開頭的所有端口掃描一下呢?;
- 從97行開始,是配置ES的分詞。
slave 節點
Slave 節點配置如下。該配置文件內容只列出了配置項,但是是完整的。
1: # ======================== Elasticsearch Configuration =========================
2: #
3: # ---------------------------------- Cluster -----------------------------------
4: #
5: # Use a descriptive name for your cluster:
6: #
7: cluster.name: myfirstcluster
8: #
9: # ------------------------------------ Node ------------------------------------
10: #
11: # Use a descriptive name for the node:
12: #
13: node.name: es-02
14: node.master: true
15: node.data: true
16: #
17: # ----------------------------------- Paths ------------------------------------
18: #
19: # Path to directory where to store the data (separate multiple locations by comma):
20: #
21: # path.data: /path/to/data
22: #
23: # Path to log files:
24: #
25: # path.logs: /path/to/logs
26: #
27: # ----------------------------------- Memory -----------------------------------
28: #
29: # ...
30: #
31: # ---------------------------------- Network -----------------------------------
32: #
33: # Set the bind address to a specific IP (IPv4 or IPv6):
34: #
35: network.host: 192.168.1.3
36: #
37: # Set a custom port for HTTP:
38: #
39: http.port: 9200
40: transport.tcp.port: 9300
41: #
42: # --------------------------------- Discovery ----------------------------------
43: #
44: # Pass an initial list of hosts to perform discovery when new node is started:
45: # The default list of hosts is ["127.0.0.1", "[::1]"]
46: #
47: discovery.zen.ping.unicast.hosts: ["192.168.1.2:9300"]
48: #
49: # ---------------------------------- Gateway -----------------------------------
50: #
51: # ...
52: #
53: # ---------------------------------- Various -----------------------------------
54: # ...
55:
56: index:
57: analysis:
58: tokenizer:
59: my_pinyin:
60: type: pinyin
61: first_letter: prefix
62: padding_char: ''
63: pinyin_first_letter:
64: type: pinyin
65: first_letter: only
66: mmseg_maxword:
67: type: mmseg
68: seg_type: max_word
69: mmseg_complex:
70: type: mmseg
71: seg_type: complex
72: mmseg_simple:
73: type: mmseg
74: seg_type: simple
75: semicolon_spliter:
76: type: pattern
77: pattern: ";"
78: pct_spliter:
79: type: pattern
80: pattern: "[%]+"
81: ngram_1_to_2:
82: type: nGram
83: min_gram: 1
84: max_gram: 2
85: ngram_1_to_3:
86: type: nGram
87: min_gram: 1
88: max_gram: 3
89: filter:
90: ngram_min_3:
91: max_gram: 10
92: min_gram: 3
93: type: nGram
94: ngram_min_2:
95: max_gram: 10
96: min_gram: 2
97: type: nGram
98: ngram_min_1:
99: max_gram: 10
100: min_gram: 1
101: type: nGram
102: min2_length:
103: min: 2
104: max: 4
105: type: length
106: min3_length:
107: min: 3
108: max: 4
109: type: length
110: pinyin_first_letter:
111: type: pinyin
112: first_letter: only
113: analyzer:
114: lowercase_keyword:
115: type: custom
116: filter:
117: - lowercase
118: tokenizer: standard
119: lowercase_keyword_ngram_min_size1:
120: type: custom
121: filter:
122: - lowercase
123: - stop
124: - trim
125: - unique
126: tokenizer: nGram
127: lowercase_keyword_ngram_min_size2:
128: type: custom
129: filter:
130: - lowercase
131: - min2_length
132: - stop
133: - trim
134: - unique
135: tokenizer: nGram
136: lowercase_keyword_ngram_min_size3:
137: type: custom
138: filter:
139: - lowercase
140: - min3_length
141: - stop
142: - trim
143: - unique
144: tokenizer: ngram_1_to_3
145: lowercase_keyword_ngram:
146: type: custom
147: filter:
148: - lowercase
149: - stop
150: - trim
151: - unique
152: tokenizer: ngram_1_to_3
153: lowercase_keyword_without_standard:
154: type: custom
155: filter:
156: - lowercase
157: tokenizer: keyword
158: lowercase_whitespace:
159: type: custom
160: filter:
161: - lowercase
162: tokenizer: whitespace
163: ik:
164: alias:
165: - ik_analyzer
166: type: ik
167: ik_max_word:
168: type: ik
169: use_smart: false
170: ik_smart:
171: type: ik
172: use_smart: true
173: mmseg:
174: alias:
175: - mmseg_analyzer
176: type: mmseg
177: mmseg_maxword:
178: type: custom
179: filter:
180: - lowercase
181: tokenizer: mmseg_maxword
182: mmseg_complex:
183: type: custom
184: filter:
185: - lowercase
186: tokenizer: mmseg_complex
187: mmseg_simple:
188: type: custom
189: filter:
190: - lowercase
191: tokenizer: mmseg_simple
192: comma_spliter:
193: type: pattern
194: pattern: "[,|\\s]+"
195: pct_spliter:
196: type: pattern
197: pattern: "[%]+"
198: custom_snowball_analyzer:
199: type: snowball
200: language: English
201: simple_english_analyzer:
202: type: custom
203: tokenizer: whitespace
204: filter:
205: - standard
206: - lowercase
207: - snowball
208: edge_ngram:
209: type: custom
210: tokenizer: edgeNGram
211: filter:
212: - lowercase
213: pinyin_ngram_analyzer:
214: type: custom
215: tokenizer: my_pinyin
216: filter:
217: - lowercase
218: - nGram
219: - trim
220: - unique
221: pinyin_first_letter_analyzer:
222: type: custom
223: tokenizer: pinyin_first_letter
224: filter:
225: - standard
226: - lowercase
227: pinyin_first_letter_keyword_analyzer:
228: alias:
229: - pinyin_first_letter_analyzer_keyword
230: type: custom
231: tokenizer: keyword
232: filter:
233: - pinyin_first_letter
234: - lowercase
235: path_analyzer: #used for tokenize :/something/something/else
236: type: custom
237: tokenizer: path_hierarchy
238:
239: #index.analysis.analyzer.default.type: mmseg
240: index.analysis.analyzer.default.type: ik
說明:
- 第7行,也是指定了集群名稱;
- 第13行,指定了節點名稱為 es-02(主機名)
- 第14和15行,指定了該節點可能成為 master 節點,還可以是數據節點;
- 第35行,指定節點IP地址為 192.168.1.3;
- 第39行,指定http端口,你使用head、kopf等相關插件使用的端口;
- 第40行,集群內部通信端口,用於節點發現等;
上面的配置master也是這么配置的。
- 第47行,跟master節點配置不一樣了。這里直接告訴該的節點,可能的master節點是什么。