Hello xin chào các bạn, là mình nha :))) Xin lỗi các bạn vì mình đã vắng bóng 1 thời gian. Lần quay trở lại này chúng ta sẽ cùng tiếp tục tìm hiểu thêm về một Service tìm kiếm được mang tên là Elasticsearch.
YO bắt đầu thôi nào.
I. Elasticsearch là gì.!?
Elasticsearch là một công cụ tìm kiếm dựa trên nền tảng Apache Lucene
. Nó cung cấp một bộ máy tìm kiếm dạng phân tán, có đầy đủ công cụ với một giao diện web HTTP có hỗ trợ dữ liệu JSON. Elasticsearch được phát triển bằng Java và được phát hành dạng nguồn mở theo giấy phép Apache.
Lý thuyết thế thôi, có rất nhiều bài đã giới thiệu cũng như nói rõ hơn về Elasticsearch rồi. Mình sẽ tóm tắt nó lại các ý chính như sau:
Elasticsearch
là mộtsearch engine
.Elasticsearch
được kế thừa từLucene Apache
Elasticsearch
thực chất hoặt động như 1 web server, có khả năng tìm kiếm nhanh chóng (near realtime) thông qua giao thức RESTfulElasticsearch
có khả năng phân tích và thống kê dữ liệuElasticsearch
chạy trên server riêng và đồng thời giao tiếp thông qua RESTful do vậy nên nó không phụ thuộc vào client viết bằng gì hay hệ thống hiện tại của bạn viết bằng gì. Nên việc tích hợp nó vào hệ thống bạn là dễ dàng, bạn chỉ cần gửi request http lên là nó trả về kết quả.Elasticsearch
là 1 hệ thống phân tán và có khả năng mở rộng tuyệt vời (horizontal scalability). Lắp thêm node cho nó là nó tự động auto mở rộng cho bạn.Elasticsearch
là 1open source
được phát triển bằngJava
Những khái niệm cần biết:
1. Document: Là một JSON object với một số dữ liệu. Đây là basic information unit trong ES. Hiểu 1 cách cơ bản thì đây là đơn vị nhỏ nhất để lưu trữ dữ liệu trong Elasticsearch
.
2. Index: Index
có lẽ là 1 khái niệm quá quen thuộc đối với các anh em dùng Mysql
rồi. Khi đọc đến đây có lẽ ae đã thừa hiểu chức năng của index
là gì rồi. Tuy nhiên nếu các bạn nghĩ rằng index
trong ES
hoàn toàn giống trong Mysql
thì các bạn nhầm rồi nhé ! Trong Elasticsearch
, sử dụng một cấu trúc được gọi là inverted index
. Nó được thiết kế để cho phép tìm kiếm full-text search
. Cách thức của nó khá đơn giản, các văn bản được phân tách ra thành từng từ có nghĩa sau đó sẽ đk map xem thuộc văn bản nào. Khi search tùy thuộc vào loại search sẽ đưa ra kết quả cụ thể.
3. Shard: Là đối tượng của Lucene
, là tập con các documents
của 1 Index. Một Index có thể được chia thành nhiều shard. Mỗi node
bao gồm nhiều Shard
. Chính vì thế Shard
mà là đối tượng nhỏ nhất, hoạt động ở mức thấp nhất, đóng vai trò lưu trữ dữ liệu.
Chúng ta gần như không bao giờ làm việc trực tiếp với các Shard
vì Elasticsearch
đã support toàn bộ việc giao tiếp cũng như tự động thay đổi các Shard
khi cần thiết.
Có 2 loại Shard
là : primary shard
và replica shard.
- Primary shard: Sẽ lưu trữ dữ liệu và đánh
index
. Sau khi đánh xong dữ liệu sẽ được vận chuyển tới cácReplica Shard
.
Mặc định củaElasticsearch
là mỗiindex
sẽ có 5Primary shard
và với mỗiPrimary shard
thì sẽ đi kèm với 1Replica Shard
. - Replica shard:
Replica Shard
đúng như cái tên của nó, nó là nơi lưu trữ dữ liệu nhân bản củaPrimary shard.
có vai trò đảm bảo tính toàn vẹn của dữ liệu khi
Replica ShardPrimary Shard
xảy ra vấn đề.
Ngoài raReplica Shard
có thể giúp tăng cường tốc độ tìm kiếm vì chúng ta có thể setup lượngReplica Shard
nhiều hơn mặc định củaElasticsearch.
4. Node: Là trung tâm hoạt động của Elasticsearch. Là nơi lưu trữ dữ liễu ,tham gia thực hiện đánh index
của cluster
cũng như thực hiện các thao tác tìm kiếm. Mỗi node
được định danh bằng 1 unique name.
5. Cluster: Tập hợp các nodes
hoạt động cùng với nhau, chia sẽ cùng thuộc tính cluster.name
. Chính vì thế Cluster
sẽ được xác định bằng 1 'unique name'. Việc định danh các cluster
trùng tên sẽ gây nên lỗi cho các node vì vậy khi setup các bạn cần hết sức chú ý điểm này.
Chức năng chính của Cluster
đó chính là quyết định xem shards
nào được phân bổ cho node
nào và khi nào thì di chuyển các Cluster
để cân bằng lại Cluster
II. Triển khai service
Qua các bài viết trước nay chúng ta sẽ cùng áp dụng hết tất cả những gì chúng ta đã tìm hiểu nhé.
- Docker.
- Gin framework.
- Golang (Tất nhiên rồi , chúng ta đang trong seri "Golang bí kiếp học" cơ mà.
Lẹt đu đ...à Let's do it:))))
1. Config service
Tạo file docker-compose.yaml
với nội dung như sau:
Với file config này thì chúng ta sẽ thiết lập được cho 2 service.
- api: Cho phép Go chạy trên local host với port là 8080
- elasticsearch: Sẽ chạy phiên bản chính thức của elascticsearch của Docker.
Tạo thư mục app
và khởi tạo project với dep.
$ mkdir search-api
$ cd search-api
$ dep init
Tạo file dockerfile
cho api
service trong thư mụcapp
.
2. Kết nối tới elasticsearch
Tạo filemain.go
trong thư mụcapp
.
Khai báo index và type của Elaticsearch
Chúng ta có dữ liệu từ Postgres như sau.
Vì vậy chúng ta sẽ khai báo cấu trúc cho nó như sau.
Tại func main() chúng ta sẽ tạo client của elasticsearch
Có một sự khác biệt về thời gian giữa một Docker container khởi động và dịch vụ bên trong nó sẵn sàng để kết nối. Vì lý do đó, đoạn mã trên cố gắng kết nối lại với dịch vụ elaticsearch cứ sau 3 giây, nếu nó bị lỗi.
Sau đó chúng ta cũng sẽ khai báo và tạo func kết nối tới Postgres
Tạo một func hỗ trợ trả về kết quả bị lỗi.
Tạo func CreateCustomer
để xử lý việc tạo index.
Tiếp đến là việc lấy dữ liệu từ Postgres lên.
Khi đã lấy được dữ liệu từ Postgres lên chúng ta sẽ thêm nó vào index của elasticsearch bằng hàm Index() được cung cấp sẵn trong gói package của olivere/elastic
.
Mình lại sử dụng lại c.JSON ở đây để kiểm tra status của request trả về, nếu thành công sẽ xuất ra màn hình thông tin của user.
Chúng ta chạy thử nhé. Các bạn nhớ phải run docker chứa image của elasticsearch mà chúng ta đã config nhé.
$ docker-compose up -d --build
Và dữ liệu đã được lấy lên từ Postgres và cũng đã được thêm vào index rồi.
Chúng ta thử chạy trên port của elasticsearch thử nhé.
Và chúng ta đã thấy được dữ liệu đã được thêm vào index customer, type user mà chúng ta đã khai báo. Và ở lệnh trên mình sử dụng "?pretty" để trả kết quả về là Json để chúng ta dễ đọc hơn.
Vậy là chúng ta đã hoàn thành được func tạo index cũng như là lấy dữ liệu từ Postgres insert vào index rồi. Cùng hoàn thiện 2 client search và update còn lại nhé.
Client search
Chạy thử trên Postman, chúng ta sẽ truyền vào key là id, và value là id của user chúng ta muốn search.
Client update
Tại đây mình cũng sẽ cập nhật dữ liệu trên index cũng như mình sẽ cập nhật dữ liệu này xuống Postgres luôn để giữ được tính đồng nhất dữ liệu nhé.
Kiểm tra dữ liệu ở Postgres nào.
Vậy là chúng ta đã update được lại ví tiền của user rồi, lần này hơi đắng cho "Đệ Nhất Quốc Sư Hoa Kỳ Nhà Tiên Tri Vũ Trụ Trần Dần" của chúng ta chắc lấy tiền bao gái :))) nên trong người chỉ còn lại 699k trong người :)))
Đến đây thì thôi chắc mình cũng như "Đệ Nhất Quốc Sư Hoa Kỳ Nhà Tiên Tri Vũ Trụ Trần Dần" phải kiếm lại ví tiền của mình thôi :))) Qua bài viết này hi vọng các bạn đã hiểu hơn về ElasticSearch cũng như có thể tạo cho mình một service riêng. Hi vọng sẽ sớm gặp lại các bạn trong phần tiếp theo của Seri "Go lang bí kiếp học" nhé.
Cảm ơn các bạn đã bỏ chút ít thời gian xem bài viết của mình, mình sẽ để lại source đã demo cùng các bạn nãy giờ tại Git Hub nhé.!!
Xin chào các bạn và hẹn gặp lại Bái bai......Yeah yeah yeah yeah yeah :)))