Cài đặt ClickHouse trên macOS và Kiểm thử với Node.js
ClickHouse là một cơ sở dữ liệu cột mã nguồn mở, được thiết kế để thực hiện các truy vấn phân tích hiệu suất cao. Hướng dẫn này sẽ hướng dẫn bạn cách cài đặt ClickHouse trên macOS, chạy nó ở chế độ nền bằng cách sử dụng nohup, lưu trữ nhật ký và PID trong các thư mục ẩn của người dùng, và kiểm thử với một ví dụ Node.js + TypeScript tối thiểu sử dụng @clickhouse/client.
Mục tiêu và Lợi ích
- Cài đặt ClickHouse: Hướng dẫn từng bước để cài đặt ClickHouse trên macOS một cách dễ dàng.
- Chạy ClickHouse trong nền: Giải thích cách chạy dịch vụ ClickHouse mà không ảnh hưởng đến phiên làm việc của bạn.
- Kiểm thử với Node.js: Cung cấp ví dụ thực tế về cách kết nối và tương tác với ClickHouse bằng Node.js.
Điều kiện tiên quyết
- macOS (Intel hoặc Apple Silicon)
- Homebrew (khuyến nghị nhưng không bắt buộc để cài đặt ClickHouse)
pnpmcho quản lý gói Node (hoặcnpm/yarnnếu bạn thích)- Kiến thức cơ bản về terminal
1. Cài đặt ClickHouse trên macOS
Hướng dẫn cài đặt
Tài liệu cài đặt chính thức của ClickHouse cho macOS: ClickHouse Installation
Phương pháp đơn giản nhất thông qua Homebrew:
bash
brew install clickhouse
Lệnh này sẽ cài đặt nhị phân clickhouse. Nếu bạn sử dụng phương pháp cài đặt khác (tải nhị phân / cask), hãy điều chỉnh đường dẫn bên dưới nếu cần.
2. Chạy ClickHouse ở chế độ nền (nohup)
Hướng dẫn này sử dụng các thư mục ẩn trong thư mục chính của bạn để lưu trữ nhật ký và PID nhằm giữ cho mọi thứ gọn gàng:
- Nhật ký:
~/.logs/clickhouse/ - PID:
~/.nohup/clickhouse.pid
Tạo các thư mục (lần đầu tiên)
bash
mkdir -p ~/.logs/clickhouse
mkdir -p ~/.nohup
touch ~/.logs/clickhouse/server.log ~/.logs/clickhouse/server.err
chmod 644 ~/.logs/clickhouse/server.*
Khởi động ClickHouse ở chế độ nền
Sử dụng nhị phân clickhouse từ PATH của bạn để chạy nó ở chế độ nền với nohup:
bash
# khởi động ở chế độ nền; sử dụng nohup và ghi vào nhật ký ẩn và tệp pid
BINARY="$(which clickhouse)"
nohup "$BINARY" server > ~/.logs/clickhouse/server.log 2> ~/.logs/clickhouse/server.err & echo $! > ~/.nohup/clickhouse.pid
Lựa chọn thay thế: Sử dụng setsid, phương pháp này mạnh mẽ hơn nếu nhị phân fork:
bash
BINARY="$(which clickhouse)"
setsid "$BINARY" server > ~/.logs/clickhouse/server.log 2> ~/.logs/clickhouse/server.err < /dev/null & echo $! > ~/.nohup/clickhouse.pid
Xác minh rằng nó đã được khởi động và đang lắng nghe
bash
# kiểm tra pid/process
cat ~/.nohup/clickhouse.pid
ps -p "$(cat ~/.nohup/clickhouse.pid)" -o pid,ppid,user,args
# xem các cổng đang lắng nghe (8123 HTTP, 9000 native TCP)
sudo lsof -iTCP -sTCP:LISTEN | egrep 'clickhouse|8123|9000|9004' || true
# kiểm tra HTTP nhanh (điểm cuối HTTP của ClickHouse)
curl -sS 'http://localhost:8123/' -d 'SELECT version()' || echo "không có phản hồi http"
Nếu curl trả về chuỗi phiên bản ClickHouse, máy chủ có thể truy cập trên :8123.
Theo dõi nhật ký
bash
tail -n 200 ~/.logs/clickhouse/server.log
tail -n 200 ~/.logs/clickhouse/server.err
# theo dõi trực tiếp
tail -f ~/.logs/clickhouse/server.err
Dừng máy chủ ở chế độ nền
bash
if [ -f ~/.nohup/clickhouse.pid ]; then
kill "$(cat ~/.nohup/clickhouse.pid)" && rm -f ~/.nohup/clickhouse.pid
else
echo "Không có tệp PID tại ~/.nohup/clickhouse.pid"
fi
Nếu tiến trình không dừng lại, tìm PID daemon thật sự:
bash
ps aux | grep clickhouse | egrep -v 'grep|egrep'
3. Ứng dụng kiểm thử Node.js + TypeScript (pnpm)
Chúng ta sẽ tạo một tập lệnh TypeScript tối thiểu mà:
- kết nối đến ClickHouse HTTP (
http://localhost:8123), - tạo một bảng tạm thời
Memory, - chèn hàng bằng cách sử dụng
client.insert(...), - truy vấn và in các hàng,
- xóa bảng.
Thiết lập dự án
bash
mkdir clickhouse-test && cd clickhouse-test
pnpm init
pnpm add @clickhouse/client
pnpm add -D ts-node typescript @types/node
Thêm script start trong package.json:
json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "ts-node src/main.ts"
}
Tạo tsconfig.json:
json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
Ví dụ: src/main.ts
typescript
import { createClient } from "@clickhouse/client";
async function main() {
const client = createClient({
url: "http://localhost:8123",
username: "default",
database: "default",
application: "ts-pnpm-test",
});
console.log("pinging ClickHouse...");
if (!(await client.ping())) {
console.error(
"❌ không thể ping ClickHouse. Nó có đang chạy trên http://localhost:8123 không?",
);
process.exit(1);
}
console.log("✅ ping ok");
// tạo bảng (sử dụng động cơ Memory cho thử nghiệm)
await client.exec({
query: `
CREATE TABLE IF NOT EXISTS test_ts_pnpm (
id UInt32,
name String
) ENGINE = Memory
`,
});
// chèn hàng bằng cách sử dụng client.insert (được khuyến nghị)
await client.insert({
table: "test_ts_pnpm",
values: [
{ id: 1, name: "alice" },
{ id: 2, name: "bob" },
],
format: "JSONEachRow",
});
// chọn lại các hàng (đầu ra JSON rõ ràng)
const result = await client.query({
query: `SELECT id, name FROM test_ts_pnpm ORDER BY id`,
format: "JSON",
});
const json = (await result.json()) as {
meta: unknown[];
data: Array<{ id: number; name: string }>;
rows: number;
};
console.log("rows:", json.rows);
console.table(json.data);
// dọn dẹp
await client.exec({ query: `DROP TABLE IF EXISTS test_ts_pnpm` });
await client.close();
console.log("hoàn tất");
}
main().catch((err) => {
console.error(err);
process.exit(1);
});
Chạy thử nghiệm
bash
pnpm start
Dự kiến đầu ra:
bash
pinging ClickHouse...
✅ ping ok
rows: 2
┌─────────┬────┬─────────┐
│ (index) │ id │ name │
├─────────┼────┼─────────┤
│ 0 │ 1 │ 'alice' │
│ 1 │ 2 │ 'bob' │
└─────────┴────┴─────────┘
hoàn tất
Xử lý sự cố
Không có phản hồi trên cổng 8123
- Xác nhận rằng máy chủ đang chạy và PID từ
~/.nohup/clickhouse.pidđang sống. - Thử chạy ClickHouse ở chế độ foreground để quan sát lỗi khởi động:
bash
"$(which clickhouse)" server 2>&1 | tee ~/clickhouse-startup-debug.log
tail -n 200 ~/clickhouse-startup-debug.log
- Tìm kiếm cấu hình ClickHouse cho các cổng tùy chỉnh (
http_port,tcp_port) trong thư mục/opt/homebrew/etc/clickhouse-server/hoặc/etc/clickhouse-server/.
Tệp nhật ký trống sau nohup
- Một số nhị phân sẽ fork/daemonize sau khi khởi động. Nếu nhật ký
nohupvẫn trống, daemon thật sự có thể đang ghi vào thư mục nhật ký riêng của nó (ví dụ:/opt/homebrew/var/log/clickhouse/). - Sử dụng
setsidhoặc chạy trongtmux/screenđể ghi nhật ký một cách đáng tin cậy hơn. - Kiểm tra nhật ký thống nhất của macOS:
bash
log show --predicate 'process == "clickhouse" OR process == "clickhouse-server"' --last 1h --info | tail -n 200
Lỗi phân tích chèn
- Sử dụng
client.insert(...)hoặc gửiINSERTdưới dạng một chuỗi SQL duy nhất quaclient.exec(...). Các phương thức trợ giúp@clickhouse/clientxử lý định dạng vận chuyển chính xác.
Lỗi quyền hoặc cấu hình
- Chạy ở chế độ foreground sẽ hiển thị lỗi quyền tệp hoặc lỗi phân tích cấu hình. Sửa chữa các đường dẫn cấu hình hoặc quyền sở hữu tệp cho phù hợp.
Kết luận
Bạn đã:
- Cài đặt ClickHouse trên macOS,
- thiết lập
nohupgọn gàng lưu trữ nhật ký trong~/.logs/clickhouse/và PID trong~/.nohup/clickhouse.pid, - một thử nghiệm Node.js + TypeScript tối thiểu xác nhận khả năng kết nối đọc/ghi.
Lưu ý: Thiết lập nohup sẽ không tự động khởi động ClickHouse sau khi khởi động macOS. Sau khi khởi động lại, bạn cần chạy lại lệnh nohup để khởi động máy chủ.
Nếu bạn muốn, tôi có thể:
- cung cấp một tệp
launchdnhỏ sử dụng các đường dẫn~/.logs/~/.nohupcủa bạn để tự động khởi động khi khởi động, hoặc - tạo một tệp shell một file để quản lý start/stop/status cho bạn.
Chúc bạn benchmark tốt! 🚀