0
0
Lập trình
Admin Team
Admin Teamtechmely

Cài đặt ClickHouse trên macOS và Kiểm thử với Node.js

Đăng vào 1 tháng trước

• 7 phút đọc

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)
  • pnpm cho quản lý gói Node (hoặc npm / yarn nế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 Copy
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 Copy
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 Copy
# 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 Copy
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 Copy
# 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 Copy
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 Copy
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 Copy
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 Copy
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 Copy
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "start": "ts-node src/main.ts"
}

Tạo tsconfig.json:

json Copy
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

Ví dụ: src/main.ts

typescript Copy
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 Copy
pnpm start

Dự kiến đầu ra:

bash Copy
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 Copy
"$(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ý nohup vẫ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 setsid hoặc chạy trong tmux/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 Copy
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ửi INSERT dưới dạng một chuỗi SQL duy nhất qua client.exec(...). Các phương thức trợ giúp @clickhouse/client xử 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 nohup gọ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 launchd nhỏ sử dụng các đường dẫn ~/.logs / ~/.nohup củ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! 🚀

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào