大數據時代,搜索無處不在。搜索技術是全棧工程師必備技術之一,現在是開源時代,數不盡的資源供咱們利用,若是要本身寫一套搜索引擎無疑是浪費繩命。本節主要介紹搜索引擎開源項目elasticSearch的安裝和使用javascript
請尊重原創,轉載請註明來源網站www.shareditor.com以及原始連接地址html
首先想一下:在一篇文章裏找一個關鍵詞怎麼找?字符串匹配是最佳答案。java
而後再想一下:找到100篇文章裏包含某個關鍵詞的文章列表怎麼找?依然是關鍵詞匹配node
再繼續想:找到100000000000(一千億)篇文章裏包含某個關鍵詞的文章怎麼找?若是用關鍵詞匹配,以如今的電腦處理速度,從遠古時代到人類滅絕這麼長時間都處理不完,這時候搜索引擎要發揮做用了mysql
搜索引擎這種技術實際上從古代就有了。想象一個國家存儲各種編撰資料的部門,有幾個屋子的書,若是想找到某一本書的時候會怎麼找呢?對了,有分類目錄,先肯定要找的書籍是哪一個類別的,而後從目錄裏面找到想要找的書籍位於屋子的什麼位置,而後再去拿。搜索引擎其實就是作了生成目錄(也就是索引)的事情。那麼現在的搜索引擎是怎麼生成索引的呢?linux
要把互聯網上的資料生成索引,攏共分三步:第一步,把資料編號;第二步,把每篇資料內容切成詞;第三步,把詞和資料編號的對應關係處理成「詞=》編號列表」的形式git
這時候你就能夠迅速的找到一千億篇文章裏包含某個關鍵詞的文章了,告訴我關鍵詞是什麼,我直接就從索引裏找到了這個詞對應的文章編號列表了,搞定!把須要數萬年才能作完的工做用了不到一秒鐘就搞定了,這就是搜索引擎的魅力!github
固然,上面說的搜索引擎技術很簡單,但百度數萬工程師也不都是白吃飯的,若是想作好一個搜索引擎產品須要解決的問題就有不少了:收集網頁時要考慮全、快、穩、新、優的問題,建索引時要考慮質量、效率、賦權、週期、時效性、資源消耗等問題,搜索的時候要考慮query分析、排序、篩選、展現、性能、廣告、推薦、個性化、統計等問題,總體上要考慮地域性、容災、國際化、當地法律、反做弊、垂直需求、移動互聯網等諸多問題,因此百度大廈徹夜通明也是能夠理解的。sql
既然搜索引擎技術這麼複雜,那麼咱們何須自尋煩惱了,開源社區爲咱們提供了不少資源,世界很美好。數據庫
說到開源搜索引擎必定要用的開源項目就是lucene,它不是搜索引擎產品,而是一個類庫,並且是至今開源搜索引擎的最好的類庫沒有之一,由於只有它一個。lucene是用Java語言開發,基本上涵蓋了搜索引擎中索引和檢索兩個核心部分的所有功能,並且抽象的很是好,我後面會單獨寫數篇文章專門講lucene的使用。最後強調一遍,它是一個類庫,不是搜索引擎,你能夠比較容易的基於lucene寫一個搜索引擎。
而後要說的一個開源項目是solr,這是一個完整的搜索引擎產品,固然它底層必定是基於lucene的,毫無疑問,由於lucene是最好且惟一的搜索引擎類庫。solr使用方法請看個人另外一篇文章《教你一步步搭建和運行完整的開源搜索引擎》
最後要說的就是elasticSearch,這個開源項目也能夠說是一個產品級別的開源項目,固然它底層必定是基於lucene的,毫無疑問,由於lucene是最好且惟一的搜索引擎類庫,我認可我是唐僧。它是一種提供了RESTful api的服務,RESTful就是直接經過HTTP協議收發請求和響應,接口比較清晰簡單,是一種架構規則。話很少說,下面我就說下安裝方法和簡單使用方法,這樣更容易理解,以後我會單獨講解怎麼讓你的網站利用elasticSearch實現搜索功能
Elasticsearch(簡稱ES)是一個基於Apache Lucene(TM)的開源搜索引擎,不管在開源仍是專有領域,Lucene能夠被認爲是迄今爲止最早進、性能最好的、功能最全的搜索引擎庫。
Elasticsearch是一個基於Apache Lucene(TM)的開源搜索引擎,不管在開源仍是專有領域,Lucene能夠被認爲是迄今爲止最早進、性能最好的、功能最全的搜索引擎庫。
可是,Lucene只是一個庫。想要發揮其強大的做用,你需使用Java並要將其集成到你的應用中。Lucene很是複雜,你須要深刻的瞭解檢索相關知識來理解它是如何工做的。
Elasticsearch也是使用Java編寫並使用Lucene來創建索引並實現搜索功能,可是它的目的是經過簡單連貫的RESTful API讓全文搜索變得簡單並隱藏Lucene的複雜性。
不過,Elasticsearch不只僅是Lucene和全文搜索引擎,它還提供:
並且,全部的這些功能被集成到一臺服務器,你的應用能夠經過簡單的RESTful API、各類語言的客戶端甚至命令行與之交互。上手Elasticsearch很是簡單,它提供了許多合理的缺省值,並對初學者隱藏了複雜的搜索引擎理論。它開箱即用(安裝便可使用),只需不多的學習既可在生產環境中使用。Elasticsearch在Apache 2 license下許可以使用,能夠免費下載、使用和修改。
隨着知識的積累,你能夠根據不一樣的問題領域定製Elasticsearch的高級特性,這一切都是可配置的,而且配置很是靈活。
以上內容來自 [百度百科]
Elasticsearch有幾個核心概念。從一開始理解這些概念會對整個學習過程有莫大的幫助。
(1) 接近實時(NRT)
Elasticsearch是一個接近實時的搜索平臺。這意味着,從索引一個文檔直到這個文檔可以被搜索到有一個輕微的延遲(一般是1秒)。
(2) 集羣(cluster)
一個集羣就是由一個或多個節點組織在一塊兒,它們共同持有你整個的數據,並一塊兒提供索引和搜索功能。一個集羣由一個惟一的名字標識,這個名字默認就是「elasticsearch」。這個名字是重要的,由於一個節點只能經過指定某個集羣的名字,來加入這個集羣。在產品環境中顯式地設定這個名字是一個好習慣,可是使用默認值來進行測試/開發也是不錯的。
(3) 節點(node)
一個節點是你集羣中的一個服務器,做爲集羣的一部分,它存儲你的數據,參與集羣的索引和搜索功能。和集羣相似,一個節點也是由一個名字來標識的,默認狀況下,這個名字是一個隨機的漫威漫畫角色的名字,這個名字會在啓動的時候賦予節點。這個名字對於管理工做來講挺重要的,由於在這個管理過程當中,你會去肯定網絡中的哪些服務器對應於Elasticsearch集羣中的哪些節點。
一個節點能夠經過配置集羣名稱的方式來加入一個指定的集羣。默認狀況下,每一個節點都會被安排加入到一個叫作「elasticsearch」的集羣中,這意味着,若是你在你的網絡中啓動了若干個節點,並假定它們可以相互發現彼此,它們將會自動地造成並加入到一個叫作「elasticsearch」的集羣中。
在一個集羣裏,只要你想,能夠擁有任意多個節點。並且,若是當前你的網絡中沒有運行任何Elasticsearch節點,這時啓動一個節點,會默認建立並加入一個叫作「elasticsearch」的集羣。
(4) 索引(index)
一個索引就是一個擁有幾分類似特徵的文檔的集合。好比說,你能夠有一個客戶數據的索引,另外一個產品目錄的索引,還有一個訂單數據的索引。一個索引由一個名字來標識(必須所有是小寫字母的),而且當咱們要對對應於這個索引中的文檔進行索引、搜索、更新和刪除的時候,都要使用到這個名字。索引相似於關係型數據庫中Database的概念。在一個集羣中,若是你想,能夠定義任意多的索引。
(5) 類型(type)
在一個索引中,你能夠定義一種或多種類型。一個類型是你的索引的一個邏輯上的分類/分區,其語義徹底由你來定。一般,會爲具備一組共同字段的文檔定義一個類型。好比說,咱們假設你運營一個博客平臺而且將你全部的數據存儲到一個索引中。在這個索引中,你能夠爲用戶數據定義一個類型,爲博客數據定義另外一個類型,固然,也能夠爲評論數據定義另外一個類型。類型相似於關係型數據庫中Table的概念。
(6)文檔(document)
一個文檔是一個可被索引的基礎信息單元。好比,你能夠擁有某一個客戶的文檔,某一個產品的一個文檔,固然,也能夠擁有某個訂單的一個文檔。文檔以JSON(JavaScript Object Notation)格式來表示,而JSON是一個處處存在的互聯網數據交互格式。
在一個index/type裏面,只要你想,你能夠存儲任意多的文檔。注意,儘管一個文檔,物理上存在於一個索引之中,文檔必須被索引/賦予一個索引的type。文檔相似於關係型數據庫中Record的概念。實際上一個文檔除了用戶定義的數據外,還包括_index
、_type
和_id
字段。
(7) 分片和複製(shards & replicas)
一個索引能夠存儲超出單個結點硬件限制的大量數據。好比,一個具備10億文檔的索引佔據1TB的磁盤空間,而任一節點都沒有這樣大的磁盤空間;或者單個節點處理搜索請求,響應太慢。
爲了解決這個問題,Elasticsearch提供了將索引劃分紅多份的能力,這些份就叫作分片。當你建立一個索引的時候,你能夠指定你想要的分片的數量。每一個分片自己也是一個功能完善而且獨立的「索引」,這個「索引」能夠被放置到集羣中的任何節點上。
分片之因此重要,主要有兩方面的緣由:
至於一個分片怎樣分佈,它的文檔怎樣聚合回搜索請求,是徹底由Elasticsearch管理的,對於做爲用戶的你來講,這些都是透明的。
在一個網絡/雲的環境裏,失敗隨時均可能發生,在某個分片/節點不知怎麼的就處於離線狀態,或者因爲任何緣由消失了。這種狀況下,有一個故障轉移機制是很是有用而且是強烈推薦的。爲此目的,Elasticsearch容許你建立分片的一份或多份拷貝,這些拷貝叫作複製分片,或者直接叫複製。複製之因此重要,主要有兩方面的緣由:
總之,每一個索引能夠被分紅多個分片。一個索引也能夠被複制0次(意思是沒有複製)或屢次。一旦複製了,每一個索引就有了主分片(做爲複製源的原來的分片)和複製分片(主分片的拷貝)之別。分片和複製的數量能夠在索引建立的時候指定。在索引建立以後,你能夠在任什麼時候候動態地改變複製數量,可是不能改變分片的數量。
默認狀況下,Elasticsearch中的每一個索引被分片5個主分片和1個複製,這意味着,若是你的集羣中至少有兩個節點,你的索引將會有5個主分片和另外5個複製分片(1個徹底拷貝),這樣的話每一個索引總共就有10個分片。一個索引的多個分片能夠存放在集羣中的一臺主機上,也能夠存放在多臺主機上,這取決於你的集羣機器數量。主分片和複製分片的具體位置是由ES內在的策略所決定的。
以上部份內容轉自Elasticsearch基礎教程,並對其進行了補充。
從github下載1.7版tag並編譯(選擇1.7版是由於當前咱們的網站的symfony2版本還不支持2.x版本,但請放心的用,1.7版是通過無數人驗證過的最穩定版本)
wget https://codeload.github.com/elastic/elasticsearch/tar.gz/v1.7.5
解壓後進入目錄執行
mvn package -DskipTests
這會花費你很長一段時間,你能夠去喝喝茶了
編譯完成後會在target/releases中生成編譯好的壓縮包(相似於elasticsearch-1.7.5.zip這樣的文件),把這個壓縮包解壓放到任意目錄就安裝好了
ik是一箇中文切詞插件,elasticSearch自帶的中文切詞很不專業,ik對中文切詞支持的比較好。
在https://github.com/medcl/elasticsearch-analysis-ik上找到咱們elasticSearch對應的版本,1.7.5對應的ik版本是1.4.1,因此下載https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v1.4.1
解壓出的目錄是:
elasticsearch-analysis-ik-1.4.1
進入目錄後執行
mvn clean package
編譯完後依然是在target/releases生成了相似於elasticsearch-analysis-ik-*.zip的壓縮包,把裏面的內容解壓到elasticsearch安裝目錄的plugins/ik下
再把elasticsearch-analysis-ik-1.4.1/config/ik目錄總體拷貝到elasticsearch安裝目錄的config下
修改elasticsearch安裝目錄下的config/elasticsearch.yml,添加:
index:
analysis:
analyzer:
ik:
alias: [ik_analyzer]
type: org.elasticsearch.index.analysis.IkAnalyzerProvider
ik_max_word:
type: ik
use_smart: false
ik_smart:
type: ik
use_smart: true
這樣ik就安裝好了
直接進入elasticsearch安裝目錄,執行
./bin/elasticsearch -d
後臺啓動完成
elasticSearch是經過HTTP協議收發數據的,因此咱們用curl命令來給它發命令,elasticSearch默認監聽9200端口
寫入一篇文章:
curl -XPUT 'http://localhost:9200/myappname/myblog/1?pretty' -d '
{
"title": "個人標題",
"content": "個人內容"
}'
會收到返回信息:
{
"_index" : "myappname",
"_type" : "myblog",
"_id" : "1",
"_version" : 1,
"created" : true
}
這說明咱們成功把一篇文章發給了elasticSearch,它底層會利用lucene自動幫咱們建好搜索用的索引
再寫一篇文章:
curl -XPUT 'http://localhost:9200/myappname/myblog/2?pretty' -d '
{
"title": "這是第二篇標題",
"content": "這是第二篇內容"
}'
會收到返回信息:
{
"_index" : "myappname",
"_type" : "myblog",
"_id" : "2",
"_version" : 1,
"created" : true
}
請尊重原創,轉載請註明來源網站www.shareditor.com以及原始連接地址
這時咱們找到elasticsearch安裝目錄的data目錄下會生成這樣的目錄和文件:
ls data/nodes/0/indices/myappname/
0 1 2 3 4 _state
不一樣環境會稍有不一樣,可是都會生成myappname目錄就對了
查看全部文章:
curl -XGET 'http://localhost:9200/myappname/myblog/_search?pretty=true' -d '
{
"query" : {
"match_all" : {}
}
}'
這時會把咱們剛纔添加的兩篇文章都列出來
搜索關鍵詞「個人」:
curl -XGET 'http://localhost:9200/myappname/myblog/_search?pretty=true' -d '
{
"query":{
"query_string":{"query":"個人"}
}
}'
會返回:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.191783,
"hits" : [ {
"_index" : "myappname",
"_type" : "myblog",
"_id" : "1",
"_score" : 0.191783,
"_source":
{
"title": "個人標題",
"content": "個人內容"
}
} ]
}
}
搜索關鍵詞「第二篇」:
curl -XGET 'http://localhost:9200/myappname/myblog/_search?pretty=true' -d '
{
"query":{
"query_string":{"query":"第二篇"}
}
}'
會返回:
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.1879082,
"hits" : [ {
"_index" : "myappname",
"_type" : "myblog",
"_id" : "2",
"_score" : 0.1879082,
"_source":
{
"title": "這是第二篇標題",
"content": "這是第二篇內容"
}
} ]
}
}
若是想檢查ik的切詞效果,能夠執行:
curl 'http://localhost:9200/myappname/_analyze?analyzer=ik_max_word&pretty=true' -d'
{
"text":"中華人民共和國國歌"
}'
經過返回結果能夠看出,ik_max_word切詞把中華人民共和國國歌切成了「中華人民共和國」、「中華人民」、「中華」、「華人」、「人民共和國」、「人民」、「共和國」、「共和」、「國」、「國歌」
也就是說咱們搜索這些詞中的任意一個都能把這句話搜到,若是不安裝ik插件的話,那隻會切成:「中」、「華」、「人」、「民」、「共」、「和」、「國」、「國」、「歌」,不夠智能,搜索也很差進行了
上面幾條命令都是json形式,elasticSearch就是這麼人性化,沒治了。
這裏面的myappname是你本身能夠改爲本身應用的名字,這在elasticSearch數據存儲中是徹底隔離的,而myblog是咱們在同一個app中想要維護的不一樣的數據,就是你的不一樣數據,好比文章、用戶、評論,他們最好都分開,這樣搜索的時候也不會混
pretty參數就是讓返回的json有換行和縮進,容易閱讀,調試時能夠加上,開發到程序裏就能夠去掉了
analyzer就是切詞器,咱們指定的ik_max_word在前面配置文件裏遇到過,表示最大程度切詞,各類切,360度切
返回結果裏的hits就是「命中」,total是命中了幾條,took是花了幾毫秒,_score就是相關性程度,能夠用來作排序的依據
上面都是json的接口,那麼咱們怎麼用呢?其實你想怎麼用就怎麼用,煎着吃、炒着吃、燉着吃都行。好比咱們的博客網站,當你建立一篇博客的時候能夠發送「添加」的json命令,而後你開發一個搜索頁面,當你輸入關鍵詞點搜索的時候,能夠發送查詢的命令,這樣返回的結果就是你的搜索結果,只不過須要你本身潤色一下,讓展示更美觀。感受複雜嗎?下一節告訴你怎麼用symfony2的擴展來實現博客網站的搜索功能
————————————————————————————————————————————————————
簡介
開始學es,我習慣邊學邊記,總結出現的問題和解決方法。本文是在兩臺Linux虛擬機下,安裝了三個節點。本次搭建es同時實踐了兩種模式——單機模式和分佈式模式。條件容許的話,能夠在多臺機器上配置es節點,若是你機器性能有限,那麼能夠在一臺虛擬機上完成多節點的配置。
如圖,是本次3個節點的分佈。
虛擬機主機名 | IP | es節點 |
---|---|---|
master | 192.168.137.100 | node一、node3 |
slave | 192.168.137.101 | node2 |
index: es裏的index至關於一個數據庫。
type: 至關於數據庫裏的一個表。
id: 惟一,至關於主鍵。
node:節點是es實例,一臺機器能夠運行多個實例,可是同一臺機器上的實例在配置文件中要確保http和tcp端口不一樣(下面有講)。
cluster:表明一個集羣,集羣中有多個節點,其中有一個會被選爲主節點,這個主節點是能夠經過選舉產生的,主從節點是對於集羣內部來講的。
shards:表明索引分片,es能夠把一個完整的索引分紅多個分片,這樣的好處是能夠把一個大的索引拆分紅多個,分佈到不一樣的節點上,構成分佈式搜索。分片的數量只能在索引建立前指定,而且索引建立後不能更改。
replicas:表明索引副本,es能夠設置多個索引的副本,副本的做用一是提升系統的容錯性,當個某個節點某個分片損壞或丟失時能夠從副本中恢復。二是提升es的查詢效率,es會自動對搜索請求進行負載均衡。
名稱 | 版本 | 下載地址 |
---|---|---|
elasticsearch | 1.7.3 | elasticsearch-1.7.3.tar.gz |
下載後,放到你的目錄下並解壓. 由於咱們要配置包含三個節點的集羣,能夠先將其重命名爲elasticsearch-node1。好比個人是 /home/zkpk/elasticsearch-node1。
(1) 初步修改
打開/home/zkpk/elasticsearch-node1/config目錄下的elasticsearch.yml 文件 ,修改如下屬性值並取消該行的註釋:
cluster.name: elasticsearch
#這是集羣名字,咱們 起名爲 elasticsearch。es啓動後會將具備相同集羣名字的節點放到一個集羣下。
node.name: "es-node1"
#節點名字。
covery.zen.minimum_master_nodes: 2
#指定集羣中的節點中有幾個有master資格的節點。對於大集羣能夠寫3個以上。
discovery.zen.ping.timeout: 40s
#默認是3s,這是設置集羣中自動發現其它節點時ping鏈接超時時間,爲避免由於網絡差而致使啓動報錯,我設成了40s。
discovery.zen.ping.multicast.enabled: false
#設置是否打開多播發現節點,默認是true。
network.bind_host: 192.168.137.100
#設置綁定的ip地址,這是個人master虛擬機的IP。
network.publish_host: 192.168.137.100
#設置其它節點和該節點交互的ip地址。
network.host: 192.168.137.100
#同時設置bind_host和publish_host上面兩個參數。
discovery.zen.ping.unicast.hosts: ["192.168.137.100", "192.168.137.101","192.168.137.100:9301"]
#discovery.zen.ping.unicast.hosts:["節點1的 ip","節點2 的ip","節點3的ip"]
指明集羣中其它可能爲master的節點ip,以防es啓動後發現不了集羣中的其餘節點。第一對引號裏是node1,默認端口是9300。第二個是 node2 ,在另一臺機器上。第三個引號裏是node3,由於它和node1在一臺機器上,因此指定了9301端口。
(2) 進一步修改
拷貝 elasticsearch-node1 整個文件夾,兩份,一份elasticsearch-node2,一份elasticsearch-node3.
將elasticsearch-node2 文件夾copy到另一臺IP爲192.168.137.101的機器上。而在 192.168.137.100 機器上有 node1和node3.
對於node3: node3和node1在一臺機器上,node1的配置文件裏端口默認分別是9300和9200,因此要改一下node3配置文件裏的端口,elasticsearch.yml 文件修改以下:
node.name: "es-node3"
transport.tcp.port: 9301
http.port: 9201
對於node2: 對 elasticsearch.yml 修改以下
node.name: "es-node2"
network.bind_host: 192.168.137.101
network.publish_host: 192.168.137.101
network.host: 192.168.137.101
注意:
1.對於單機多節點的es集羣,必定要注意修改 transport.tcp.port 和http.port 的默認值保證節點間不衝突。
2. 出現找不到同一集羣中的其餘節點的狀況,檢查下 discovery.zen.ping.unicast.hosts 是否已設置。
編輯 /home/zkpk/elasticsearch-1.7.3/bin/elasticsearch.in.sh, 設置 ES_MIN_MEM和ES_MAX_MEM,確保兩者數值一致,或者能夠在啓動es時指定,
若想讓es後臺運行,則
[zkpk@master bin]$ ./elasticsearch -d -Xms512m -Xmx512m
前臺運行:能夠經過」CTRL+C」組合鍵來中止運行
後臺運行,能夠經過」kill -9 進程號」中止.也能夠經過REST API接口:
curl -XPOST http://主機IP:9200/_cluster/nodes/_shutdown
來關閉整個集羣,經過:
curl -XPOST http://主機IP:9200/_cluster/nodes/節點標示符(如es-node1)/_shutdown
來關閉單個節點.
BigDesk Plugin : 對集羣中es狀態進行監控。
Elasticsearch Head Plugin: 對ES進行各類操做,如查詢、刪除、瀏覽索引等。
進入到節點elasticsearch-node1/bin路徑,並安裝插件。
[zkpk@master bin]$ ./plugin -install mobz/elasticsearch-head
[zkpk@master bin]$ ./plugin -install lukas-vlcek/bigdesk
打開head瀏覽,瀏覽器輸入http://192.168.137.100:9200/_plugin/head/ ,如圖,
每一個小方塊就是索引分片,能夠看到每一個索引被分紅幾個分片,每一個分片還有它的備份分片,而後存儲在三個節點上。粗框的是主分片,細框的是備份分片。
如今咱們來添加一個索引記錄吧~
curl -XPUT 'http://主機IP:9200/dept/employee/32' -d '{ "empname": "emp32"}'
見 http://www.oschina.net/translate/elasticsearch-getting-started?cmp
(1)點擊 複合查詢[+] ,咱們能夠在 megacorp 索引 (至關於數據庫名)的 employee 類型(至關於表名)下新增一個id爲2的人的信息。
點擊下方的 提交請求 按鈕,頁面右方有回饋信息,「created」表明是否爲新建。添加成功。
點擊 瀏覽數據 ,在左側 索引 下選擇 megacorp,如圖,
能夠看到,一條id爲2的記錄被添加了。
(2)下面咱們修改id爲2 的人的年齡爲15,把about 信息去掉,而且加一項興趣。
提交後,右側有反饋信息,「created」爲 false,由於咱們此次不是新建而是修改。
返回瀏覽數據,id爲2 的記錄,年齡、興趣等均已發生變化。
參考:
http://www.cnblogs.com/huangfox/p/3543351.html
http://www.linuxidc.com/Linux/2015-02/114243.htm
http://my.oschina.net/u/579033/blog/394845?fromerr=Kt60ej6x