Nút thắt cổ chai tìm kiếm trong các cơ sở dữ liệu truyền thống
Tôi từng xử lý một dự án danh mục sản phẩm với khoảng 5 triệu bản ghi lưu trữ trong PostgreSQL. Hiệu năng rất tuyệt vời cho đến khi khách hàng yêu cầu một thanh tìm kiếm kiểu “Google”. Họ cần tìm kiếm mờ (fuzzy matching), tính điểm mức độ liên quan (relevance scoring) và kết quả tức thì trên hàng chục cột. Mặc dù MySQL và PostgreSQL là những cái tên sừng sỏ cho dữ liệu có cấu trúc, chúng không được thiết kế cho loại tác vụ nặng nề đặc thù này.
Toán tử LIKE '%keyword%' của SQL là một cái bẫy hiệu năng. Nó buộc cơ sở dữ liệu phải quét toàn bộ bảng (full table scan), điều này có thể chấp nhận được với 10.000 dòng nhưng là một thảm họa với 5 triệu dòng. Trong trường hợp của chúng tôi, thời gian truy vấn đã tăng vọt từ 50ms lên gần 4 giây khi tập dữ liệu lớn dần. Để giải quyết vấn đề này, bạn cần một inverted index (chỉ mục đảo ngược). Trong nhiều năm, Elasticsearch là tiêu chuẩn, nhưng những thay đổi về giấy phép đã thúc đẩy cộng đồng hướng tới một giải pháp thay thế mã nguồn mở thực sự: OpenSearch.
Tại sao chọn OpenSearch?
OpenSearch là một nhánh (fork) do cộng đồng thúc đẩy từ Elasticsearch 7.10.2. Nó giữ nguyên RESTful API mà có thể bạn đã quen thuộc, giúp việc thay thế cho các ứng dụng hiện có trở nên dễ dàng. Nó xuất sắc ở hai nhiệm vụ cốt lõi: Full-text search để tìm kiếm tài liệu dựa trên ý định và Phân tích Log (Log Analytics) để xử lý hàng triệu sự kiện dạng chuỗi thời gian (time-series).
Hãy coi nó là động cơ đằng sau OSD stack (OpenSearch, Fluentd/Logstash, và Dashboards). Nếu ứng dụng của bạn đang bị nghẽn bởi các truy vấn văn bản hoặc bạn cần tập trung log từ 50 microservices khác nhau, OpenSearch là con đường đáng tin cậy nhất. Hãy cùng chạy nó trên máy của bạn bằng Docker.
Điều kiện tiên quyết của hệ thống
Trước khi tải bất kỳ image nào, bạn phải điều chỉnh một thiết lập hệ thống quan trọng. OpenSearch dựa vào mmapfs để lưu trữ các chỉ mục. Hầu hết các bản phân phối Linux đều đặt giới hạn memory map mặc định quá thấp, khiến container OpenSearch bị crash ngay lập tức với lỗi “out of memory”.
Chạy lệnh này trên máy chủ Linux của bạn để tăng giới hạn lên mức yêu cầu là 262,144:
sudo sysctl -w vm.max_map_count=262144
Để thay đổi này có hiệu lực sau khi khởi động lại, hãy thêm vm.max_map_count=262144 vào tệp /etc/sysctl.conf của bạn. Nếu bạn đang sử dụng Docker Desktop trên Windows hoặc Mac, bạn có thể cần chạy lệnh này bên trong máy ảo cơ sở.
Triển khai với Docker Compose
Docker Compose là cách gọn gàng nhất để quản lý công cụ tìm kiếm và giao diện web của nó (Dashboards) cùng nhau. Hãy tạo một thư mục dự án mới và thêm tệp docker-compose.yml. Chúng tôi khuyên bạn nên có ít nhất 4GB RAM trống trên máy chủ để có trải nghiệm mượt mà.
Cấu hình bên dưới sẽ vô hiệu hóa plugin bảo mật. Điều này hữu ích cho việc phát triển cục bộ (local development), nhưng đừng bao giờ làm điều này trong môi trường production. Luôn sử dụng SSL/TLS và xác thực mạnh khi công khai dữ liệu tìm kiếm lên internet.
version: '3.8'
services:
opensearch-node:
image: opensearchproject/opensearch:2.11.0
container_name: opensearch-node
environment:
- cluster.name=opensearch-cluster
- node.name=opensearch-node
- discovery.type=single-node
- bootstrap.memory_lock=true
- "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
- DISABLE_INSTALL_DEMO_CONFIG=true
- DISABLE_SECURITY_PLUGIN=true
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- osdata:/usr/share/opensearch/data
ports:
- 9200:9200
networks:
- opensearch-net
opensearch-dashboards:
image: opensearchproject/opensearch-dashboards:2.11.0
container_name: opensearch-dashboards
ports:
- 5601:5601
environment:
- 'OPENSEARCH_HOSTS=["http://opensearch-node:9200"]'
- "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true"
networks:
- opensearch-net
volumes:
osdata:
networks:
opensearch-net:
Khởi chạy stack bằng một lệnh duy nhất:
docker-compose up -d
Hãy để các dịch vụ khởi động trong khoảng 30 đến 60 giây. Bạn có thể theo dõi tiến trình bằng cách xem log: docker logs -f opensearch-node.
Xác minh cài đặt
Kiểm tra xem API đã hoạt động chưa bằng cách truy cập vào cổng mặc định. Sử dụng curl hoặc bất kỳ trình duyệt nào để truy cập endpoint trạng thái.
curl http://localhost:9200
Bạn sẽ thấy một phản hồi JSON chứa số phiên bản (ví dụ: “2.11.0”) và khẩu hiệu “The OpenSearch Project: https://opensearch.org/”. Nếu nội dung đó xuất hiện, công cụ của bạn đã sẵn sàng.
Bây giờ, hãy truy cập http://localhost:5601 trên trình duyệt của bạn. Thao tác này sẽ mở OpenSearch Dashboards. Đây là một GUI mạnh mẽ cho phép bạn trực quan hóa dữ liệu, quản lý các chỉ mục và kiểm tra các truy vấn mà không cần viết các lệnh curl phức tạp.
Lập chỉ mục và Tìm kiếm dữ liệu
OpenSearch sử dụng thuật ngữ khác với SQL. Bạn không có “bảng” (table); bạn có chỉ mục (index). Bạn không có “hàng” (row); bạn có tài liệu (document). Hãy cùng thực hành.
1. Thêm một tài liệu
Chúng ta sẽ tạo một chỉ mục có tên là books và thêm một mục nhập. OpenSearch là schema-less (không yêu cầu lược đồ), vì vậy nó sẽ tự động nhận diện “publish_date” là ngày tháng và “title” là chuỗi văn bản.
curl -X PUT "http://localhost:9200/books/_doc/1" -H 'Content-Type: application/json' -d'
{
"title": "Dự án Phoenix (The Phoenix Project)",
"author": "Gene Kim",
"category": "IT & DevOps",
"summary": "Một cuốn tiểu thuyết về IT, DevOps và giúp doanh nghiệp của bạn giành chiến thắng.",
"publish_date": "2013-01-10"
}'
2. Chạy tìm kiếm Full-Text
Đây là lúc phép màu xảy ra. Chúng ta sẽ tìm kiếm từ “doanh nghiệp” trong trường summary. OpenSearch sử dụng thuật toán BM25 để tính toán điểm mức độ liên quan cho mỗi tài liệu mà nó tìm thấy.
curl -X GET "http://localhost:9200/books/_search" -H 'Content-Type: application/json' -d'
{
"query": {
"match": {
"summary": "doanh nghiệp"
}
}
}'
Phản hồi bao gồm một trường _score. Nếu bạn có 100 cuốn sách đề cập đến “doanh nghiệp”, những cuốn sách có từ này xuất hiện nổi bật nhất sẽ nằm ở đầu danh sách.
Trường hợp sử dụng thực tế: Phân tích Log
Tìm kiếm sách là một chuyện, nhưng khắc phục sự cố một hệ thống phân tán lại là chuyện khác. Khi bạn có 50 microservices, việc SSH vào từng máy chủ để đọc log là điều bất khả thi. Bằng cách đẩy log vào OpenSearch thông qua Fluent Bit, bạn có thể tìm kiếm qua 100GB dữ liệu trong vài mili giây.
Trong giao diện Dashboards, hãy sử dụng tab Discover để lọc log theo tên dịch vụ hoặc mức độ lỗi. Bạn có thể xây dựng một biểu đồ tròn thời gian thực hiển thị mã lỗi 404 so với 500 hoặc biểu đồ đường theo dõi độ trễ của yêu cầu. Khả năng hiển thị này là sự khác biệt giữa một sự cố kéo dài 5 phút và một sự cố kéo dài 5 giờ.
Lời kết
Việc chuyển từ các truy vấn SQL cơ bản sang một công cụ chuyên dụng như OpenSearch sẽ thay đổi quy trình phát triển của bạn. Bạn sẽ ngừng phải vật lộn với việc quét cơ sở dữ liệu chậm chạp và bắt đầu xây dựng các tính năng mà người dùng thực sự yêu thích. Docker giúp việc khởi tạo một instance để thử nghiệm trở nên cực kỳ đơn giản, và vì nó tương thích API với Elasticsearch, bạn có thể sử dụng hầu hết mọi thư viện hoặc công cụ hiện có trong hệ sinh thái.
Cho dù bạn đang xây dựng một trang thương mại điện tử hay một hệ thống giám sát, OpenSearch cung cấp một nền tảng mã nguồn mở hiệu năng cao, có khả năng mở rộng khi dữ liệu của bạn lớn dần.

