+6

[Phỏng vấn BE]: Elasticsearch là gì?

I. Giới thiệu

Elasticsearch là một search engine mạnh mẽ, dựa trên nền tảng lucene, cho phép lưu trữ, tìm kiếm và phân tích dữ liệu thời gian thực với khả năng mở rộng cao. Hãy cùng mình tìm hiểu một chút về nó nhé.

II. Tại sao sử dụng

1. Tìm kiếm mạnh mẽ

Đơn giản thôi, elasticsearch có khả năng tìm kiểm near-realtime, mình từng dùng postgres để search dữ liệu sản phẩm, response time thường từ 200ms-500ms, nhưng sau khi mình áp dụng elasticsearch thì response time trả về chỉ còn xx ms (tính cả response của backend, network). Ngoài ra nó cung cấp các tính năng hay ho cho tìm kiếm toàn văn như:

  • Fuzzy search: cho phép tìm kiếm gần đúng, hữu ích khi xử lý lỗi chính tả.
  • Highlighting: đánh dấu các từ khóa tìm kiếm trong kết quả.
  • Suggestions: đề xuất các từ khóa tương tự khi không tìm thấy kết quả chính xác. Ví dụ bạn tìm từ ô tô nó có thể trả về từ đồng nghĩa như xe hơi, điều này là bất khả thi với database khác.
  • Hỗ trợ các loại dữ liệu không gian địa lý như geo_pointgeo_shape. Cung cấp các queries đặc biệt như geo_distance và geo_bounding_box cho tìm kiếm dựa trên vị trí.
  • Có thể tùy chỉnh để xử lý các ngôn ngữ đặc biệt.

2. Mở rộng và hiệu suất cao

  • Kiến trúc phân tán cho phép mở rộng dễ dàng theo chiều ngang.
  • Được thiết kế để xử lý hàng tỷ bản ghi với độ trễ thấp.

III. Cơ chế hoạt động của Elasticsearch

1. Apache Lucene và sự khác biệt

Elasticsearch được xây dựng trên nền tảng Apache Lucene - một thư viện tìm hỗ trợ tìm kiếm toàn văn. Nhưng apache sinh ra với nhiều hạn chế, và elasticsearch sinh ra để giải quyết vấn đề đó:

  • Lucene:

    • Thư viện Java thuần túy, nếu bạn không biết code java thì toang rồi, sao dùng bây giờ. Mà kể cả biết thì cũng khó mà dùng.
    • Tập trung vào chức năng tìm kiếm cốt lõi.
  • Elasticsearch:

    • Cung cấp API RESTful, ngôn ngữ nào cũng được, miễn nhận RESTful là dùng được.
    • Hệ thống phân tán, có khả năng mở rộng cao.
    • Dễ dàng triển khai và quản lý cluster.
    • Cung cấp các tính năng bổ sung như aggregations, machine learning.

2. Inverted Index

Inverted Index là cấu trúc dữ liệu cốt lõi cho phép Elasticsearch thực hiện tìm kiếm full-text nhanh chóng. Cách inverted index được tổ chức (từ từ khoá -> danh sách documents)

Hãy tưởng tượng inverted index giống như mục lục ở một cuốn sách. Thay vì liệt kê các chương, nó liệt kê các từ quan trọng và số trang mà chúng xuất hiện. Mình sẽ đề cập chi tiết cách nó tìm kiếm ở phần sau.

3. Tokenization

Tokenization là quá trình tách văn bản thành các đơn vị nhỏ hơn, gọi là token. Mỗi token thường là một từ hoặc cụm từ, và quá trình này là bước quan trọng trong việc phân tích văn bản để lập chỉ mục hoặc tìm kiếm. Quá trình phân tích sẽ gồm các bước sau:

  1. Tokenization: Chia văn bản thành các tokens.
  2. Normalization: Chuyển đổi tokens thành dạng chuẩn hóa (ví dụ: lowercase).
  3. Indexing: Lưu trữ các tokens và liên kết chúng với documents.

4. Thuật toán chấm điểm (Scoring Algorithm)

Elasticsearch sử dụng các thuật toán chấm điểm để xác định độ liên quan của kết quả tìm kiếm:

TF-IDF (Term Frequency-Inverse Document Frequency):

  • Term Frequency: Số lần xuất hiện của term trong document.
  • Inverse Document Frequency: Đánh giá tầm quan trọng của term trong toàn bộ văn bản.

BM25 (Okapi BM25):

  • Cải tiến của TF-IDF, xem xét độ dài của document.

Tùy chỉnh scoring:

  • Sử dụng function_score query để áp dụng các hàm boost tùy chỉnh.
  • Áp dụng field-level boosting để ưu tiên các trường quan trọng.

IV. Elasticsearch vs database truyền thống

Để hiểu rõ hơn về sức mạnh của Elasticsearch, hãy so sánh nó với PostgreSQL trong một trường hợp tìm kiếm cụ thể:

1. Ví dụ: Tìm kiếm từ khóa "bút chì" trong danh sách sản phẩm

Id name description
1 cậu bé bút chì màu Truyện tranh
2 chiếc bút chì kim đồ dùng học tập
3 shin truyện tranh về shin cậu bé bút chì mới nhất

Tìm kiếm trong PostgreSQL:

SELECT * FROM product WHERE name ILIKE '%bút chì%' OR description ILIKE '%bút chì%';

Quá trình xử lý:

  1. PostgreSQL sẽ quét qua toàn bộ bảng product (full table scan), trừ khi có index phù hợp.
  2. Với mỗi row, nó sẽ kiểm tra xem chuỗi "bút chì" có xuất hiện trong trường name hoặc description không.
  3. Việc sử dụng ILIKE với wildcard ở cả hai đầu (%...%) ngăn cản việc sử dụng index hiệu quả, ngay cả khi có.
  4. Thời gian xử lý tăng tuyến tính với số lượng records trong bảng. Ưu điểm:
  • Đơn giản, dễ implement
  • Chính xác cho exact substring matching Nhược điểm:
  • Chậm với dữ liệu lớn
  • Không hỗ trợ tốt cho tìm kiếm ngôn ngữ tự nhiên (ví dụ: không xử lý được từ đồng nghĩa, gần nghĩa)
  • Không có scoring mechanism để sắp xếp kết quả theo độ liên quan

Tìm kiếm trong Elasticsearch:

{
  "query": {
    "multi_match": {
      "query": "bút chì",
      "fields": ["name", "description"],
      "type": "best_fields"
    }
  }
}

Quá trình xử lý:

  1. Elasticsearch sử dụng inverted index để nhanh chóng định vị các documents chứa từ "bút" và "chì".

  2. Insert:

    Trong bước insert, nó sẽ tiến hành các bước để xử lý ngôn ngữ tự nhiên, đánh inverted index cho document này:

    • Tokenization: tách "bút chì" thành ["bút", "chì"]
    • Normalization: chuyển về dạng chuẩn (ví dụ: lowercase)
    • Có thể áp dụng stemming/lemmatization nếu được cấu hình
  3. Tìm kiếm các documents chứa cả "bút" và "chì" trong name hoặc description thông qua index đã được đánh từ trước.

  4. Tính toán relevance score cho mỗi kết quả.

  5. Trả về kết quả đã được sắp xếp theo relevance score cao nhất trước.

V. Các trường hợp sử dụng phổ biến của Elasticsearch

Elasticsearch có thể được áp dụng trong nhiều lĩnh vực khác nhau:

  • Full-text search: Tìm kiếm nhanh chóng trong lượng lớn dữ liệu văn bản.
  • Phân tích log: Tập trung và phân tích log từ nhiều nguồn khác nhau.
  • Metrics: Thu thập và visualize các metrics từ hệ thống và ứng dụng.
  • Security analytics: Phát hiện các mối đe dọa và anomalies trong dữ liệu bảo mật.

Trong phần sau mình sẽ giới thiệu cách mình đã áp dụng elasticsearch vào dự án thực tế như thế nào.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.