Quickwit cung cấp tính năng Search Stream mạnh mẽ, cho phép truyền tải danh sách ID hoặc thuộc tính khớp với truy vấn tìm kiếm thông qua giao thức REST với tốc độ cực cao (lên tới 50 triệu bản ghi mỗi giây). ClickHouse có thể tận dụng luồng dữ liệu này để thực hiện các truy vấn JOIN, từ đó bổ sung khả năng tìm kiếm toàn văn (full-text search) vốn không phải là thế mạnh của các cơ sở dữ liệu OLAP truyền thống.
Trong hướng dẫn này, chúng ta sẽ sử dụng bộ dữ liệu GitHub Archive bao gồm hàng tỷ sự kiện như PullRequestEvent hay IssuesEvent để minh họa cách kết hợp hai công cụ này.
Cài đặt Quickwit
Đầu tiên, bạn cần tải và giải nén Quickwit trên hệ thống của mình:
curl -L https://install.quickwit.io | sh
cd quickwit-v*/
Khởi chạy dịch vụ Quickwit:
./quickwit run
Thiết lập Index trong Quickwit
Chúng ta cần định nghĩa một cấu hình index để lưu trữ các trường cần thiết cho việc tìm kiếm. Giả sử dữ liệu đầu vào có cấu trúc như sau:
{
"id": 11410577343,
"event_type": "PullRequestEvent",
"actor_login": "developer_x",
"repo_name": "org/repo",
"created_at": 1580515200,
"title": "Fix memory leak in worker",
"body": "This PR addresses the issue reported in..."
}
Tạo file cấu hình gh-index-config.yaml. Lưu ý rằng chúng ta chỉ cần index các trường như title và body để tìm kiếm, còn trường id sẽ được dùng để ánh xạ với ClickHouse.
version: 0.7
index_id: github-events-idx
doc_mapping:
store_source: false
field_mappings:
- name: id
type: u64
fast: true
- name: created_at
type: datetime
input_formats:
- unix_timestamp
output_format: unix_timestamp_secs
fast: true
- name: event_type
type: text
tokenizer: raw
- name: title
type: text
tokenizer: default
record: position
- name: body
type: text
tokenizer: default
record: position
timestamp_field: created_at
search_settings:
default_search_fields: [title, body]
Tiến hành tạo index bằng lệnh sau:
./quickwit index create --index-config gh-index-config.yaml
Nạp dữ liệu vào Quickwit
Sử dụng tập dữ liệu mẫu (dạng NDJSON nén) để nạp vào hệ thống:
wget https://quickwit-datasets-public.s3.amazonaws.com/gh-archive/gh-archive-2021-12-text-only.json.gz
gunzip -c gh-archive-2021-12-text-only.json.gz | ./quickwit index ingest --index github-events-idx
Bạn có thể kiểm tra dữ liệu đã vào hay chưa bằng một câu lệnh tìm kiếm đơn giản:
./quickwit index search --index github-events-idx --query "memory leak"
Cấu hình ClickHouse
Tiếp theo, chúng ta cần chuẩn bị bảng dữ liệu trong ClickHouse để lưu trữ thông tin chi tiết của các sự kiện GitHub.
CREATE DATABASE IF NOT EXISTS gh_analytics;
USE gh_analytics;
CREATE TABLE github_data
(
id UInt64,
event_type Enum('CommitCommentEvent' = 1, 'CreateEvent' = 2, 'DeleteEvent' = 3, 'ForkEvent' = 4,
'GollumEvent' = 5, 'IssueCommentEvent' = 6, 'IssuesEvent' = 7, 'MemberEvent' = 8,
'PublicEvent' = 9, 'PullRequestEvent' = 10, 'PullRequestReviewCommentEvent' = 11,
'PushEvent' = 12, 'ReleaseEvent' = 13, 'SponsorshipEvent' = 14, 'WatchEvent' = 15,
'GistEvent' = 16, 'FollowEvent' = 17, 'DownloadEvent' = 18, 'PullRequestReviewEvent' = 19,
'ForkApplyEvent' = 20, 'Event' = 21, 'TeamAddEvent' = 22),
actor_login LowCardinality(String),
repo_name LowCardinality(String),
created_at Int64,
action Enum('none' = 0, 'created' = 1, 'added' = 2, 'edited' = 3, 'deleted' = 4, 'opened' = 5, 'closed' = 6, 'reopened' = 7, 'assigned' = 8, 'unassigned' = 9,
'labeled' = 10, 'unlabeled' = 11, 'review_requested' = 12, 'review_request_removed' = 13, 'synchronize' = 14, 'started' = 15, 'published' = 16, 'update' = 17, 'create' = 18, 'fork' = 19, 'merged' = 20),
comment_id UInt64,
body String,
ref LowCardinality(String),
number UInt32,
title String,
additions UInt32,
deletions UInt32,
commit_id String
) ENGINE = MergeTree ORDER BY (event_type, repo_name, created_at);
Nạp dữ liệu vào ClickHouse:
wget https://quickwit-datasets-public.s3.amazonaws.com/gh-archive/gh-archive-2021-12.json.gz
gunzip -c gh-archive-2021-12.json.gz | clickhouse-client -d gh_analytics --query="INSERT INTO github_data FORMAT JSONEachRow"
Sử dụng Search Stream để truy vấn
Sức mạnh thực sự nằm ở việc kết hợp URL table engine của ClickHouse với API của Quickwit. Chúng ta sẽ lấy danh sách ID từ Quickwit và dùng nó làm bộ lọc cho truy vấn trong ClickHouse.
Ví dụ: Tìm kiếm các sự kiện liên quan đến từ khóa "log4j" và thống kê theo ngày.
SELECT
count(*) AS total_events,
toDate(fromUnixTimestamp64Milli(created_at)) AS event_date
FROM github_data
WHERE id IN (
SELECT id
FROM url(
'http://127.0.0.1:7280/api/v1/github-events-idx/search/stream?query=log4j&fast_field=id&output_format=click_house_row_binary',
RowBinary,
'id UInt64'
)
)
GROUP BY event_date
ORDER BY event_date ASC;
Trong truy vấn trên:
- Quickwit xử lý việc tìm kiếm toàn văn trên các trường text lớn và trả về luồng ID dưới định dạng
RowBinarycực nhanh. - ClickHouse nhận luồng ID này và thực hiện phép lọc
INtrên bảnggithub_datađã được tối ưu hóa cho phân tích.
Phương pháp này cho phép bạn tận dụng tốc độ xử lý dữ liệu lớn của ClickHouse mà vẫn có khả năng tìm kiếm linh hoạt của Quickwit mà không cần phải lưu trữ trùng lặp quá nhiều dữ liệu text trong ClickHouse.