Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Vì ClickHouse là một hệ thống chuyên biệt nên khi sử dụng nó, điều quan trọng là phải tính đến các đặc điểm kiến ​​trúc của nó. Trong báo cáo này, Alexey sẽ nói về những ví dụ về những lỗi thường gặp khi sử dụng ClickHouse có thể dẫn đến công việc không hiệu quả. Các ví dụ thực tế sẽ cho thấy việc chọn một hoặc một sơ đồ xử lý dữ liệu khác có thể thay đổi hiệu suất theo mức độ lớn như thế nào.

Chào mọi người! Tên tôi là Alexey, tôi làm ClickHouse.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Đầu tiên tôi xin làm hài lòng các bạn ngay hôm nay, hôm nay tôi sẽ không nói cho các bạn biết ClickHouse là gì. Thành thật mà nói, tôi mệt mỏi vì nó. Lần nào tôi cũng nói cho bạn biết nó là gì. Và có lẽ mọi người cũng đã biết.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Thay vào đó, tôi sẽ cho bạn biết những lỗi có thể xảy ra, đó là cách bạn có thể sử dụng ClickHouse không chính xác. Trên thực tế, không cần phải lo lắng vì chúng tôi đang phát triển ClickHouse như một hệ thống đơn giản, tiện lợi và hoạt động hiệu quả. Tôi đã cài đặt nó, không có vấn đề gì.

Nhưng bạn vẫn cần lưu ý rằng hệ thống này là hệ thống chuyên biệt và bạn có thể dễ dàng gặp một trường hợp sử dụng bất thường sẽ khiến hệ thống này thoát ra khỏi vùng an toàn của nó.

Vậy có loại cào nào? Chủ yếu tôi sẽ nói về những điều hiển nhiên. Mọi thứ đều hiển nhiên đối với mọi người, mọi người đều hiểu mọi thứ và có thể vui mừng vì mình rất thông minh, còn những người không hiểu sẽ học được điều gì đó mới.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Ví dụ đầu tiên và đơn giản nhất, thật không may, thường xảy ra, là một số lượng lớn các phần chèn với các lô nhỏ, tức là một số lượng lớn các phần chèn nhỏ.

Nếu chúng tôi xem xét cách ClickHouse thực hiện thao tác chèn thì bạn có thể gửi ít nhất một terabyte dữ liệu trong một yêu cầu. Không vấn đề gì.

Và hãy xem màn trình diễn điển hình sẽ như thế nào. Ví dụ: chúng tôi có một bảng từ dữ liệu Yandex.Metrica. Lượt truy cập. 105 một số cột. 700 byte không nén. Và chúng tôi sẽ chèn một cách tốt theo từng đợt một triệu hàng.

Chúng tôi chèn MergeTree vào bảng, kết quả là nửa triệu hàng mỗi giây. Tuyệt vời. Trong một bảng được sao chép, nó sẽ nhỏ hơn một chút, khoảng 400 hàng mỗi giây.

Và nếu bạn kích hoạt tính năng chèn đại biểu, bạn sẽ nhận được hiệu suất ít hơn một chút nhưng vẫn ở mức khá, 250 thuật ngữ mỗi giây. Chèn đại biểu là một tính năng không có giấy tờ trong ClickHouse*.

* tính đến năm 2020, đã được ghi lại.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Điều gì xảy ra nếu bạn làm điều gì đó xấu? Chúng tôi chèn một hàng vào bảng MergeTree và nhận được 59 hàng mỗi giây. Tức là chậm hơn 10 lần. Trong ReplicadMergeTree - 000 hàng mỗi giây. Và nếu bạn bật đại biểu thì sẽ có 6 dòng mỗi giây. Theo ý kiến ​​​​của tôi, đây là một loại tào lao tuyệt đối. Làm sao có thể chậm lại như vậy? Tôi thậm chí còn viết trên áo phông của mình rằng ClickHouse không nên chạy chậm lại. Nhưng tuy nhiên đôi khi nó vẫn xảy ra.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Thực ra đây chính là điểm yếu của chúng tôi. Chúng tôi có thể dễ dàng làm cho mọi thứ hoạt động tốt, nhưng chúng tôi đã không làm vậy. Và chúng tôi đã không làm điều đó vì kịch bản của chúng tôi không yêu cầu điều đó. Chúng tôi đã có thịt rồi. Chúng tôi vừa nhận được các lô hàng ở lối vào và không có vấn đề gì. Chúng tôi chèn nó và mọi thứ hoạt động tốt. Nhưng tất nhiên mọi tình huống đều có thể xảy ra. Ví dụ: khi bạn có một loạt máy chủ để tạo dữ liệu. Và họ không chèn dữ liệu thường xuyên nhưng cuối cùng họ vẫn thường xuyên chèn dữ liệu. Và chúng ta cần phải tránh điều này bằng cách nào đó.

Từ quan điểm kỹ thuật, vấn đề là khi bạn thực hiện thao tác chèn vào ClickHouse, dữ liệu sẽ không xuất hiện trong bất kỳ bảng ghi nhớ nào. Chúng tôi thậm chí không có cấu trúc nhật ký thực sự MergeTree mà chỉ có MergeTree, vì không có nhật ký hay memTable. Chúng tôi chỉ cần ghi ngay dữ liệu vào hệ thống tệp đã được sắp xếp theo cột. Và nếu bạn có 100 cột thì hơn 200 tệp sẽ cần được ghi vào một thư mục riêng. Tất cả điều này là rất cồng kềnh.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Và câu hỏi đặt ra: “Làm thế nào cho đúng?” Nếu tình huống đó xảy ra mà bạn vẫn cần ghi lại dữ liệu trong ClickHouse bằng cách nào đó.

Cách 1. Đây là cách dễ nhất. Sử dụng một số loại hàng đợi phân phối. Ví dụ như Kafka. Bạn chỉ cần trích xuất dữ liệu từ Kafka và xử lý dữ liệu theo nhóm mỗi giây một lần. Và mọi thứ sẽ ổn thôi, bạn ghi lại, mọi thứ đều hoạt động tốt.

Nhược điểm là Kafka là một hệ thống phân tán cồng kềnh khác. Tôi cũng hiểu nếu bạn đã có Kafka trong công ty của mình. Nó tốt, nó thuận tiện. Nhưng nếu nó không tồn tại thì bạn nên suy nghĩ kỹ trước khi kéo một hệ thống phân tán khác vào dự án của mình. Và vì vậy, đáng để xem xét các lựa chọn thay thế.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Phương pháp 2. Đây là một giải pháp thay thế kiểu cũ và đồng thời rất đơn giản. Bạn có loại máy chủ nào tạo nhật ký của mình không. Và nó chỉ ghi nhật ký của bạn vào một tập tin. Và chẳng hạn, cứ sau một giây, chúng tôi đổi tên tệp này và xé một tệp mới. Và một tập lệnh riêng biệt, thông qua cron hoặc một số daemon, lấy tệp cũ nhất và ghi nó vào ClickHouse. Nếu bạn ghi nhật ký mỗi giây một lần thì mọi thứ sẽ ổn.

Nhưng nhược điểm của phương pháp này là nếu máy chủ nơi tạo nhật ký của bạn biến mất ở đâu đó thì dữ liệu cũng sẽ biến mất.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Phương pháp 3. Có một phương pháp thú vị khác, hoàn toàn không yêu cầu các tệp tạm thời. Ví dụ: bạn có một số loại công cụ quay vòng quảng cáo hoặc một số trình nền thú vị khác tạo ra dữ liệu. Và bạn có thể tích lũy nhiều dữ liệu trực tiếp vào RAM, trong bộ đệm. Và khi đã đủ thời gian, bạn đặt bộ đệm này sang một bên, tạo một bộ đệm mới và trong một chuỗi riêng biệt, chèn những gì đã tích lũy được vào ClickHouse.

Mặt khác, dữ liệu cũng biến mất với kill -9. Nếu máy chủ của bạn gặp sự cố, bạn sẽ mất dữ liệu này. Và một vấn đề khác là nếu bạn không thể ghi vào cơ sở dữ liệu thì dữ liệu của bạn sẽ tích lũy trong RAM. Và RAM sẽ hết hoặc đơn giản là bạn sẽ mất dữ liệu.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Phương pháp 4. Một phương pháp thú vị khác. Bạn có một số loại quy trình máy chủ. Và nó có thể gửi dữ liệu tới ClickHouse ngay lập tức nhưng thực hiện chỉ trong một kết nối. Ví dụ: tôi đã gửi một yêu cầu http có mã hóa chuyển: được chia nhỏ bằng phần chèn. Và nó không hiếm khi tạo ra các khối, bạn có thể gửi từng dòng, mặc dù sẽ tốn chi phí cho việc đóng khung dữ liệu này.

Tuy nhiên, trong trường hợp này dữ liệu sẽ được gửi tới ClickHouse ngay lập tức. Và ClickHouse sẽ tự đệm chúng.

Nhưng vấn đề cũng nảy sinh. Bây giờ bạn sẽ mất dữ liệu, bao gồm cả thời điểm quy trình của bạn bị hủy và liệu quy trình ClickHouse có bị hủy hay không vì đó sẽ là một phần chèn không đầy đủ. Và trong các phần chèn của ClickHouse là nguyên tử đạt đến một ngưỡng nhất định được chỉ định về kích thước của các hàng. Về nguyên tắc, đây là một cách thú vị. Cũng có thể được sử dụng.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Phương pháp 5. Đây là một phương pháp thú vị khác. Đây là một loại máy chủ do cộng đồng phát triển để xử lý dữ liệu theo khối. Bản thân tôi chưa xem nó nên tôi không thể đảm bảo bất cứ điều gì. Tuy nhiên, không có sự đảm bảo nào được cung cấp cho chính ClickHouse. Đây cũng là nguồn mở, nhưng mặt khác, bạn có thể quen với một số tiêu chuẩn chất lượng mà chúng tôi cố gắng cung cấp. Nhưng đối với điều này - tôi không biết, hãy truy cập GitHub, xem mã. Có lẽ họ đã viết một cái gì đó bình thường.

* kể từ năm 2020, cũng cần được thêm vào để xem xét Mèo ConNhà.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Phương pháp 6. Một phương pháp khác là sử dụng bảng đệm. Ưu điểm của phương pháp này là rất dễ bắt đầu sử dụng. Tạo một bảng đệm và chèn nó vào đó.

Nhược điểm là vấn đề không được giải quyết hoàn toàn. Nếu, theo tốc độ như MergeTree, bạn phải nhóm dữ liệu theo một đợt mỗi giây, thì với tốc độ trong bảng đệm, bạn cần nhóm ít nhất lên đến vài nghìn mỗi giây. Nếu trên 10 mỗi giây thì vẫn tệ. Và nếu bạn chèn nó theo từng đợt, thì bạn sẽ thấy rằng nó có tốc độ hàng trăm nghìn dòng mỗi giây. Và đây là dữ liệu khá nặng.

Và các bảng đệm cũng không có nhật ký. Và nếu có sự cố xảy ra với máy chủ của bạn thì dữ liệu sẽ bị mất.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Và như một phần thưởng, gần đây chúng tôi đã có cơ hội tại ClickHouse để lấy dữ liệu từ Kafka. Có một công cụ bàn - Kafka. Bạn chỉ cần tạo ra. Và bạn có thể treo các hình ảnh đại diện cụ thể lên đó. Trong trường hợp này, nó sẽ tự trích xuất dữ liệu từ Kafka và chèn vào các bảng bạn cần.

Và điều đặc biệt hài lòng về cơ hội này là không phải chúng tôi đã làm được điều đó. Đây là một tính năng cộng đồng. Và khi tôi nói “tính năng cộng đồng”, tôi muốn nói điều đó mà không có chút khinh thường nào. Chúng tôi đã đọc mã, đánh giá và nó sẽ hoạt động tốt.

* kể từ năm 2020, hỗ trợ tương tự đã xuất hiện cho ThỏMQ.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Điều gì khác có thể gây bất tiện hoặc bất ngờ khi chèn dữ liệu? Nếu bạn thực hiện yêu cầu chèn giá trị và viết một số biểu thức được tính toán vào các giá trị. Ví dụ: now() cũng là một biểu thức được tính toán. Và trong trường hợp này, ClickHouse buộc phải khởi chạy trình thông dịch của các biểu thức này trên mỗi dòng và hiệu suất sẽ giảm theo mức độ lớn. Tốt hơn là nên tránh điều này.

* hiện tại, sự cố đã được giải quyết hoàn toàn, không còn bất kỳ hiện tượng hồi quy hiệu suất nào khi sử dụng biểu thức trong VALUES.

Một ví dụ khác là khi có thể có một số vấn đề khi bạn có dữ liệu trên một lô thuộc nhiều phân vùng. Theo mặc định, các phân vùng ClickHouse được phân chia theo tháng. Và nếu bạn chèn một loạt hàng triệu hàng và có dữ liệu trong vài năm, thì bạn sẽ có vài chục phân vùng ở đó. Và điều này tương đương với việc sẽ có những lô có kích thước nhỏ hơn vài chục lần, vì bên trong chúng luôn được chia thành các phân vùng đầu tiên.

* Gần đây, ở chế độ thử nghiệm, ClickHouse đã thêm hỗ trợ cho định dạng nhỏ gọn của chunk và chunk trong RAM bằng nhật ký ghi trước, điều này gần như giải quyết được hoàn toàn vấn đề.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Bây giờ hãy xem loại vấn đề thứ hai - gõ dữ liệu.

Việc gõ dữ liệu có thể nghiêm ngặt hoặc chuỗi. Chuỗi là khi bạn vừa lấy nó và khai báo rằng tất cả các trường của bạn đều thuộc kiểu chuỗi. Điều này thật tệ. Không cần phải làm điều này.

Hãy cùng tìm hiểu cách thực hiện chính xác trong những trường hợp bạn muốn nói rằng chúng ta có một trường nào đó, một chuỗi và để ClickHouse tự tìm ra, tôi sẽ không bận tâm. Nhưng nó vẫn đáng để nỗ lực.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Ví dụ: chúng tôi có một địa chỉ IP. Trong một trường hợp, chúng tôi đã lưu nó dưới dạng một chuỗi. Ví dụ: 192.168.1.1. Và trong trường hợp khác, nó sẽ là một số loại UInt32*. 32 bit là đủ cho một địa chỉ IPv4.

Thứ nhất, thật kỳ lạ, dữ liệu sẽ được nén gần như bằng nhau. Tất nhiên sẽ có sự khác biệt nhưng không quá lớn. Vì vậy không có vấn đề đặc biệt nào với I/O đĩa.

Nhưng có sự khác biệt nghiêm trọng về thời gian xử lý và thời gian thực hiện truy vấn.

Hãy đếm số lượng địa chỉ IP duy nhất nếu chúng được lưu trữ dưới dạng số. Con số đó đạt tới 137 triệu dòng mỗi giây. Nếu tương tự ở dạng chuỗi thì 37 triệu dòng mỗi giây. Tôi không biết tại sao lại có sự trùng hợp này. Tôi đã tự mình thực hiện những yêu cầu này. Nhưng vẫn chậm hơn khoảng 4 lần.

Và nếu bạn tính toán sự khác biệt về dung lượng ổ đĩa thì cũng có sự khác biệt. Và sự khác biệt là khoảng một phần tư, vì có khá nhiều địa chỉ IP duy nhất. Và nếu có những dòng có một số ít ý nghĩa khác nhau, thì chúng sẽ dễ dàng được nén theo từ điển thành một tập gần như nhau.

Và sự chênh lệch múi giờ gấp bốn lần không nằm ở con đường. Tất nhiên, có thể bạn không quan tâm, nhưng khi nhìn thấy sự khác biệt như vậy, tôi thấy buồn.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Hãy xem xét các trường hợp khác nhau.

1. Một trường hợp khi bạn có một vài giá trị duy nhất khác nhau. Trong trường hợp này, chúng tôi sử dụng một phương pháp đơn giản mà bạn có thể biết và có thể sử dụng cho bất kỳ DBMS nào. Tất cả điều này đều có ý nghĩa không chỉ đối với ClickHouse. Chỉ cần viết số nhận dạng số vào cơ sở dữ liệu. Và bạn có thể chuyển đổi thành chuỗi và quay lại bên cạnh ứng dụng của mình.

Ví dụ: bạn có một khu vực. Và bạn đang cố lưu nó dưới dạng một chuỗi. Và nó sẽ được viết ở đó: Moscow và khu vực Moscow. Và khi tôi thấy nó ghi “Moscow”, thì chẳng có gì cả, nhưng khi đó là Moscow, không hiểu sao nó lại trở nên hoàn toàn buồn bã. Đây là bao nhiêu byte.

Thay vào đó, chúng tôi chỉ cần viết số Ulnt32 và 250. Chúng tôi có 250 trong Yandex, nhưng số của bạn có thể khác. Để đề phòng, tôi sẽ nói rằng ClickHouse có khả năng tích hợp sẵn để hoạt động với cơ sở địa lý. Bạn chỉ cần viết ra một thư mục có các khu vực, bao gồm cả thư mục phân cấp, tức là sẽ có Moscow, Khu vực Moscow và mọi thứ bạn cần. Và bạn có thể chuyển đổi ở cấp độ yêu cầu.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Tùy chọn thứ hai gần giống nhau nhưng có hỗ trợ bên trong ClickHouse. Đây là kiểu dữ liệu Enum. Bạn chỉ cần viết tất cả các giá trị bạn cần vào bên trong Enum. Ví dụ: loại thiết bị và viết ở đó: máy tính để bàn, thiết bị di động, máy tính bảng, TV. Có tổng cộng 4 lựa chọn.

Nhược điểm là bạn cần phải thay đổi nó định kỳ. Chỉ cần thêm một tùy chọn. Hãy làm thay đổi bảng. Trên thực tế, bảng thay đổi trong ClickHouse là miễn phí. Đặc biệt miễn phí cho Enum vì dữ liệu trên đĩa không thay đổi. Tuy nhiên, thay đổi có được một khóa* trên bàn và phải đợi cho đến khi tất cả các lựa chọn được thực thi. Và chỉ sau khi thay đổi này mới được thực hiện, tức là vẫn còn một số bất tiện.

* trong các phiên bản mới nhất của ClickHouse, ALTER được thực hiện hoàn toàn không chặn.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Một tùy chọn khác khá độc đáo cho ClickHouse là kết nối từ điển bên ngoài. Bạn có thể viết số trong ClickHouse và giữ các thư mục của bạn trong bất kỳ hệ thống nào thuận tiện cho bạn. Ví dụ: bạn có thể sử dụng: MySQL, Mongo, Postgres. Bạn thậm chí có thể tạo microservice của riêng mình để gửi dữ liệu này qua http. Và ở cấp độ ClickHouse, bạn viết một hàm sẽ chuyển đổi dữ liệu này từ số thành chuỗi.

Đây là một cách chuyên dụng nhưng rất hiệu quả để thực hiện nối trên một bảng bên ngoài. Và có hai lựa chọn. Theo một phương án, dữ liệu này sẽ được lưu trữ hoàn toàn vào bộ nhớ đệm, hiện diện đầy đủ trong RAM và được cập nhật với tần suất nhất định. Và trong một tùy chọn khác, nếu dữ liệu này không vừa với RAM, thì bạn có thể lưu vào bộ nhớ đệm một phần.

Đây là một ví dụ. Có Yandex.Direct. Và có một công ty quảng cáo và các biểu ngữ. Có lẽ có khoảng hàng chục triệu công ty quảng cáo. Và chúng gần như vừa khít với RAM. Và có hàng tỷ biểu ngữ, chúng không phù hợp. Và chúng tôi sử dụng từ điển được lưu trong bộ nhớ cache từ MySQL.

Vấn đề duy nhất là từ điển được lưu trong bộ nhớ đệm sẽ hoạt động tốt nếu tỷ lệ trúng gần 100%. Nếu nó nhỏ hơn thì khi xử lý các truy vấn cho từng lô dữ liệu, bạn thực sự sẽ phải lấy các khóa còn thiếu và đi lấy dữ liệu từ MySQL. Về ClickHouse, tôi vẫn có thể đảm bảo rằng - vâng, nó không hề chậm lại, tôi sẽ không nói về các hệ thống khác.

Và như một phần thưởng, từ điển là một cách rất dễ dàng để cập nhật dữ liệu trở về trước trong ClickHouse. Tức là bạn có một báo cáo về các công ty quảng cáo, người dùng chỉ cần thay đổi công ty quảng cáo và trong tất cả dữ liệu cũ, trong tất cả các báo cáo, dữ liệu này cũng thay đổi. Nếu bạn viết hàng trực tiếp vào bảng thì sẽ không thể cập nhật chúng.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Một cách khác khi bạn không biết lấy mã định danh cho chuỗi của mình ở đâu. bạn có thể chỉ cần băm nó. Hơn nữa, tùy chọn đơn giản nhất là lấy hàm băm 64 bit.

Vấn đề duy nhất là nếu hàm băm là 64-bit thì gần như chắc chắn bạn sẽ xảy ra xung đột. Bởi vì nếu có một tỷ dòng ở đó thì xác suất đã trở nên đáng chú ý.

Và sẽ không hay lắm nếu băm tên các công ty quảng cáo theo cách này. Nếu các chiến dịch quảng cáo của các công ty khác nhau bị trộn lẫn vào nhau thì sẽ có điều gì đó khó hiểu.

Và có một mẹo đơn giản. Đúng, nó cũng không phù hợp lắm với dữ liệu nghiêm trọng, nhưng nếu có gì đó không nghiêm trọng lắm, thì chỉ cần thêm mã định danh khách hàng vào khóa từ điển. Và sau đó bạn sẽ có xung đột, nhưng chỉ trong một khách hàng. Và chúng tôi sử dụng phương pháp này cho bản đồ liên kết trong Yandex.Metrica. Chúng tôi có URL ở đó, chúng tôi lưu trữ các giá trị băm. Và tất nhiên chúng ta biết rằng sẽ có những va chạm. Nhưng khi trang được hiển thị, có thể bỏ qua xác suất trên một trang của một người dùng, một số URL bị dính vào nhau và điều này sẽ được chú ý.

Như một phần thưởng, đối với nhiều hoạt động, chỉ cần băm là đủ và bản thân các chuỗi không cần phải được lưu trữ ở bất kỳ đâu.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Một ví dụ khác là nếu các chuỗi ngắn, chẳng hạn như tên miền trang web. Chúng có thể được lưu trữ như cũ. Hoặc, ví dụ, ngôn ngữ trình duyệt ru là 2 byte. Tất nhiên, tôi thực sự cảm thấy tiếc cho số byte, nhưng đừng lo lắng, 2 byte không phải là điều đáng tiếc. Xin hãy giữ nguyên như vậy, đừng lo lắng.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Một trường hợp khác là ngược lại, có rất nhiều dòng và có rất nhiều dòng độc đáo trong đó, và thậm chí cả bộ có khả năng không giới hạn. Một ví dụ điển hình là cụm từ tìm kiếm hoặc URL. Tìm kiếm các cụm từ, bao gồm cả lỗi chính tả. Hãy xem có bao nhiêu cụm từ tìm kiếm duy nhất mỗi ngày. Và hóa ra chúng chiếm gần một nửa số sự kiện. Và trong trường hợp này, bạn có thể nghĩ rằng bạn cần chuẩn hóa dữ liệu, đếm số nhận dạng và đặt nó vào một bảng riêng. Nhưng bạn không cần phải làm điều đó. Chỉ cần giữ những dòng này như hiện tại.

Tốt hơn hết là đừng phát minh ra bất cứ thứ gì, vì nếu bạn lưu trữ nó riêng biệt, bạn sẽ cần phải tham gia. Và sự kết hợp này tốt nhất là một quyền truy cập ngẫu nhiên vào bộ nhớ, nếu nó vẫn còn vừa trong bộ nhớ. Nếu nó không phù hợp thì sẽ có vấn đề.

Và nếu dữ liệu được lưu trữ tại chỗ thì nó chỉ cần được đọc theo thứ tự cần thiết từ hệ thống tệp và mọi thứ đều ổn.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Nếu bạn có URL hoặc một số chuỗi dài phức tạp khác, thì bạn nên cân nhắc rằng bạn có thể tính toán trước một số loại trích xuất và viết nó vào một cột riêng.

Ví dụ: đối với URL, bạn có thể lưu trữ tên miền riêng. Và nếu bạn thực sự cần một miền, thì chỉ cần sử dụng cột này và các URL sẽ nằm ở đó và bạn thậm chí sẽ không cần chạm vào chúng.

Hãy xem sự khác biệt là gì. ClickHouse có chức năng chuyên dụng để tính toán tên miền. Nó rất nhanh, chúng tôi đã tối ưu hóa nó. Và thành thật mà nói, nó thậm chí không tuân thủ RFC, nhưng tuy nhiên nó vẫn đáp ứng mọi thứ chúng tôi cần.

Và trong một trường hợp, chúng tôi sẽ chỉ lấy URL và tính toán tên miền. Tính ra là 166 mili giây. Và nếu bạn sử dụng một miền làm sẵn thì nó chỉ mất 67 mili giây, tức là nhanh hơn gần ba lần. Và nó nhanh hơn không phải vì chúng ta cần thực hiện một số phép tính mà vì chúng ta đọc ít dữ liệu hơn.

Đó là lý do tại sao một yêu cầu chậm hơn lại có tốc độ gigabyte/giây cao hơn. Bởi vì nó đọc được nhiều gigabyte hơn. Đây là dữ liệu hoàn toàn không cần thiết. Yêu cầu có vẻ chạy nhanh hơn nhưng lại mất nhiều thời gian hơn để hoàn thành.

Và nếu bạn nhìn vào lượng dữ liệu trên đĩa, hóa ra URL là 126 megabyte, còn tên miền chỉ là 5 megabyte. Hóa ra ít hơn 25 lần. Tuy nhiên, yêu cầu chỉ được thực hiện nhanh hơn 4 lần. Nhưng đó là vì dữ liệu còn nóng. Và nếu trời lạnh, có lẽ nó sẽ nhanh hơn 25 lần nhờ vào I/O đĩa.

Nhân tiện, nếu bạn ước tính một miền nhỏ hơn bao nhiêu so với URL thì nó sẽ nhỏ hơn khoảng 4 lần, nhưng vì lý do nào đó, dữ liệu chiếm ít hơn 25 lần trên đĩa. Tại sao? Do bị nén. Và URL được nén và tên miền được nén. Nhưng thường thì URL chứa rất nhiều rác.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Và tất nhiên, bạn nên sử dụng đúng loại dữ liệu được thiết kế riêng cho các giá trị mong muốn hoặc phù hợp. Nếu bạn đang sử dụng IPv4 thì hãy lưu trữ UInt32*. Nếu là IPv6 thì FixString(16), vì địa chỉ IPv6 là 128 bit, tức là được lưu trữ trực tiếp ở định dạng nhị phân.

Nhưng điều gì sẽ xảy ra nếu đôi khi bạn có địa chỉ IPv4 và đôi khi là IPv6? Có, bạn có thể lưu trữ cả hai. Một cột cho IPv4, một cột khác cho IPv6. Tất nhiên, có một tùy chọn để hiển thị IPv4 trong IPv6. Điều này cũng sẽ hiệu quả, nhưng nếu bạn thường cần địa chỉ IPv4 trong các yêu cầu thì tốt nhất nên đặt nó vào một cột riêng.

* ClickHouse hiện có các kiểu dữ liệu IPv4, IPv6 riêng biệt giúp lưu trữ dữ liệu hiệu quả dưới dạng số nhưng thể hiện chúng một cách thuận tiện dưới dạng chuỗi.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Điều quan trọng cần lưu ý là cần phải xử lý trước dữ liệu. Ví dụ: bạn nhận được một số nhật ký thô. Và có lẽ bạn không nên đưa chúng vào ClickHouse ngay lập tức, mặc dù việc không làm gì là rất hấp dẫn và mọi thứ sẽ hoạt động. Nhưng nó vẫn đáng để thực hiện các tính toán có thể.

Ví dụ: phiên bản trình duyệt. Ở một số bộ phận lân cận mà tôi không muốn chỉ tay vào, phiên bản trình duyệt được lưu trữ như thế này, tức là dưới dạng một chuỗi: 12.3. Sau đó, để lập báo cáo, họ lấy chuỗi này chia thành một mảng, rồi chia thành phần tử đầu tiên của mảng. Đương nhiên, mọi thứ đều chậm lại. Tôi hỏi tại sao họ làm điều này. Họ nói với tôi rằng họ không thích tối ưu hóa sớm. Và tôi không thích sự bi quan quá sớm.

Vì vậy trong trường hợp này sẽ đúng hơn nếu chia thành 4 cột. Đừng sợ ở đây vì đây là ClickHouse. ClickHouse là một cơ sở dữ liệu dạng cột. Và các cột nhỏ càng gọn gàng thì càng tốt. Sẽ có 5 BrowserVersions, tạo thành 5 cột. Điều này ổn.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Bây giờ hãy xem phải làm gì nếu bạn có nhiều chuỗi rất dài, mảng rất dài. Chúng hoàn toàn không cần phải được lưu trữ trong ClickHouse. Thay vào đó, bạn chỉ có thể lưu trữ số nhận dạng trong ClickHouse. Và đặt những dòng dài này vào một số hệ thống khác.

Ví dụ: một trong các dịch vụ phân tích của chúng tôi có một số thông số sự kiện. Và nếu có nhiều tham số cho các sự kiện, chúng ta chỉ cần lưu 512 đầu tiên bắt gặp. Vì 512 không phải là điều đáng tiếc.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Và nếu bạn không thể quyết định loại dữ liệu của mình thì bạn cũng có thể ghi dữ liệu trong ClickHouse, nhưng trong bảng tạm thời thuộc loại Nhật ký, đặc biệt dành cho dữ liệu tạm thời. Sau đó, bạn có thể phân tích sự phân bổ các giá trị mà bạn có ở đó, những gì nói chung và tạo các loại chính xác.

*ClickHouse hiện có kiểu dữ liệu Số lượng thấp cho phép bạn lưu trữ chuỗi hiệu quả với ít nỗ lực hơn.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Bây giờ chúng ta hãy xem xét một trường hợp thú vị khác. Đôi khi mọi thứ diễn ra một cách kỳ lạ đối với mọi người. Tôi vào và thấy cái này. Và ngay lập tức có vẻ như điều này đã được thực hiện bởi một số quản trị viên thông minh, rất giàu kinh nghiệm, người có nhiều kinh nghiệm trong việc thiết lập MySQL phiên bản 3.23.

Ở đây chúng ta thấy một nghìn bảng, mỗi bảng ghi lại phần còn lại của việc chia ai biết cái gì cho một nghìn.

Về nguyên tắc, tôi tôn trọng trải nghiệm của người khác, bao gồm cả sự hiểu biết về những đau khổ mà trải nghiệm này có thể đạt được.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Và lý do ít nhiều rõ ràng. Đây là những khuôn mẫu cũ có thể đã tích lũy khi làm việc với các hệ thống khác. Ví dụ: bảng MyISAM không có khóa chính được nhóm. Và cách phân chia dữ liệu này có thể là một nỗ lực tuyệt vọng để có được chức năng tương tự.

Một lý do khác là rất khó thực hiện bất kỳ thao tác thay đổi nào trên các bảng lớn. Mọi thứ sẽ bị chặn. Mặc dù trong các phiên bản hiện đại của MySQL, vấn đề này không còn quá nghiêm trọng nữa.

Hoặc, ví dụ: microsharding, nhưng sẽ nói thêm về điều đó sau.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Không cần phải làm điều này trong ClickHouse, vì trước hết khóa chính được nhóm lại, dữ liệu được sắp xếp theo khóa chính.

Và đôi khi mọi người hỏi tôi: “Hiệu suất của các truy vấn phạm vi trong ClickHouse thay đổi như thế nào tùy thuộc vào kích thước bảng?” Tôi nói nó không thay đổi chút nào. Ví dụ: bạn có một bảng có một tỷ hàng và bạn đọc phạm vi một triệu hàng. Mọi thứ đều ổn. Nếu có một nghìn tỷ hàng trong một bảng và bạn đọc một triệu hàng thì nó sẽ gần như giống nhau.

Và thứ hai, tất cả những thứ như phân vùng thủ công đều không bắt buộc. Nếu bạn vào và nhìn vào hệ thống tập tin có gì, bạn sẽ thấy cái bảng này là một vấn đề khá lớn. Và có một cái gì đó giống như các vách ngăn bên trong. Tức là ClickHouse làm mọi thứ cho bạn và bạn không phải chịu bất cứ khó khăn nào.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Thay đổi trong ClickHouse là miễn phí nếu thay đổi cột thêm/thả.

Và bạn không nên làm những bảng nhỏ, vì nếu bạn có 10 hàng hay 10 hàng trong một bảng thì điều đó không thành vấn đề gì cả. ClickHouse là một hệ thống tối ưu hóa thông lượng chứ không phải độ trễ nên việc xử lý 000 dòng là vô nghĩa.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Việc sử dụng một cái bàn lớn là đúng. Hãy thoát khỏi những khuôn mẫu cũ, mọi chuyện sẽ ổn thôi.

Và như một phần thưởng, trong phiên bản mới nhất, giờ đây chúng tôi có khả năng tạo khóa phân vùng tùy ý để thực hiện tất cả các loại hoạt động bảo trì trên các phân vùng riêng lẻ.

Ví dụ, bạn cần nhiều bảng nhỏ, chẳng hạn khi có nhu cầu xử lý một số dữ liệu trung gian, bạn nhận được các chunk và cần thực hiện một phép biến đổi trên chúng trước khi ghi vào bảng cuối cùng. Đối với trường hợp này, có một công cụ tạo bảng tuyệt vời - StripeLog. Nó giống như TinyLog, chỉ tốt hơn.

* bây giờ ClickHouse cũng có đầu vào hàm bảng.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Một mô hình phản mẫu khác là microsharding. Ví dụ: bạn cần phân chia dữ liệu và bạn có 5 máy chủ, ngày mai sẽ có 6 máy chủ. Và bạn nghĩ về cách cân bằng lại dữ liệu này. Và thay vào đó bạn chia không phải thành 5 mảnh mà thành 1 mảnh. Và sau đó bạn ánh xạ từng microshard này tới một máy chủ riêng biệt. Và ví dụ, bạn sẽ nhận được 000 ClickHouse trên một máy chủ. Các phiên bản riêng biệt trên các cổng riêng biệt hoặc cơ sở dữ liệu riêng biệt.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Nhưng điều này không tốt lắm ở ClickHouse. Bởi vì ngay cả một phiên bản ClickHouse cũng cố gắng sử dụng tất cả tài nguyên máy chủ có sẵn để xử lý một yêu cầu. Nghĩa là, bạn có một số loại máy chủ và nó có, chẳng hạn như 56 lõi xử lý. Bạn đang chạy một truy vấn mất một giây để hoàn thành và nó sẽ sử dụng 56 lõi. Và nếu bạn đặt 200 ClickHouses ở đó trên một máy chủ thì hóa ra 10 chủ đề sẽ bắt đầu. Nói chung mọi thứ sẽ rất tệ.

Một lý do khác là việc phân bổ công việc giữa các trường hợp này sẽ không đồng đều. Một số sẽ hoàn thành sớm hơn, một số sẽ hoàn thành muộn hơn. Nếu tất cả điều này xảy ra trong một trường hợp thì ClickHouse sẽ tự tìm ra cách phân phối dữ liệu một cách chính xác giữa các luồng.

Và một lý do khác là bạn sẽ có giao tiếp giữa các bộ xử lý thông qua TCP. Dữ liệu sẽ phải được tuần tự hóa, giải tuần tự hóa và đây là một số lượng lớn các microshard. Đơn giản là nó sẽ không hoạt động hiệu quả.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Một phản mẫu khác, mặc dù khó có thể gọi nó là một phản mẫu. Đây là một lượng lớn tổng hợp trước.

Nói chung, việc tổng hợp trước là tốt. Bạn có một tỷ hàng, bạn tổng hợp nó và nó trở thành 1 hàng và bây giờ truy vấn được thực thi ngay lập tức. Mọi thứ đều tuyệt vời. Bạn có thể làm được việc này. Và để làm được điều này, ngay cả ClickHouse cũng có một loại bảng đặc biệt, AggregatingMergeTree, thực hiện việc tổng hợp tăng dần khi dữ liệu được chèn vào.

Nhưng có những lúc bạn nghĩ rằng chúng ta sẽ tổng hợp dữ liệu như thế này và tổng hợp dữ liệu như thế này. Và ở một số bộ phận lân cận thì mình cũng không muốn nói là bộ phận nào, họ dùng bảng SummingMergeTree để tóm tắt bằng khóa chính, khoảng 20 cột dùng làm khóa chính. Để đề phòng, tôi đã đổi tên một số cột để giữ bí mật, nhưng đại khái là vậy thôi.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Và những vấn đề như vậy phát sinh. Thứ nhất, khối lượng dữ liệu của bạn không giảm quá nhiều. Ví dụ, nó giảm ba lần. Ba lần sẽ là một mức giá tốt để có được khả năng phân tích không giới hạn phát sinh nếu dữ liệu của bạn không được tổng hợp. Nếu dữ liệu được tổng hợp thì thay vì phân tích, bạn chỉ nhận được những số liệu thống kê tồi tệ.

Và nó có gì đặc biệt? Thực tế là những người ở bộ phận lân cận thỉnh thoảng đến và yêu cầu thêm một cột khác vào khóa chính. Tức là chúng tôi đã tổng hợp dữ liệu như thế này, nhưng bây giờ chúng tôi muốn nhiều hơn một chút. Nhưng ClickHouse không có khóa chính thay đổi. Vì vậy, chúng ta phải viết một số tập lệnh bằng C++. Và tôi không thích các tập lệnh, ngay cả khi chúng ở dạng C++.

Và nếu bạn xem ClickHouse được tạo ra để làm gì, thì dữ liệu không tổng hợp chính xác là bối cảnh mà nó ra đời. Nếu bạn đang sử dụng ClickHouse cho dữ liệu không tổng hợp thì bạn đang làm đúng. Nếu bạn tổng hợp, điều này đôi khi có thể tha thứ được.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Một trường hợp thú vị khác là truy vấn trong vòng lặp vô hạn. Đôi khi tôi đến một số máy chủ sản xuất và xem danh sách quy trình hiển thị ở đó. Và mỗi lần tôi phát hiện ra điều gì đó khủng khiếp đang xảy ra.

Ví dụ như thế này. Rõ ràng là mọi thứ đều có thể được thực hiện chỉ trong một yêu cầu. Chỉ cần viết url vào và danh sách ở đó.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Tại sao nhiều truy vấn như vậy trong một vòng lặp vô tận lại không tốt? Nếu một chỉ mục không được sử dụng thì bạn sẽ có nhiều lần chuyển qua cùng một dữ liệu. Nhưng nếu chỉ mục được sử dụng chẳng hạn, thì bạn có khóa chính cho ru và bạn viết url = gì đó ở đó. Và bạn nghĩ rằng nếu chỉ có một URL được đọc từ bảng thì mọi thứ sẽ ổn. Nhưng thực tế là không. Bởi vì ClickHouse thực hiện mọi thứ theo đợt.

Khi cần đọc một phạm vi dữ liệu nhất định, anh ấy đọc nhiều hơn một chút, vì chỉ mục trong ClickHouse rất thưa thớt. Chỉ mục này không cho phép bạn tìm thấy một hàng riêng lẻ trong bảng, chỉ một phạm vi nào đó. Và dữ liệu được nén theo khối. Để đọc được một dòng, bạn cần lấy cả khối và mở khóa nó. Và nếu bạn đang thực hiện nhiều truy vấn, bạn sẽ có nhiều truy vấn trùng lặp và bạn sẽ có rất nhiều việc phải làm đi làm lại.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Và như một phần thưởng, bạn có thể lưu ý rằng trong ClickHouse, bạn không nên ngại chuyển ngay cả megabyte và thậm chí hàng trăm megabyte sang phần IN. Tôi nhớ từ thực tế của chúng tôi rằng nếu trong MySQL, chúng tôi chuyển một loạt giá trị sang phần IN, chẳng hạn như chúng tôi chuyển 100 megabyte của một số số ở đó, thì MySQL sẽ ngốn hết 10 gigabyte bộ nhớ và không có gì khác xảy ra với nó, mọi thứ đều như vậy hoạt động kém.

Và thứ hai là trong ClickHouse, nếu các truy vấn của bạn sử dụng một chỉ mục thì nó luôn không chậm hơn so với quét toàn bộ, tức là nếu bạn cần đọc gần như toàn bộ bảng, nó sẽ đi tuần tự và đọc toàn bộ bảng. Nói chung, anh ấy sẽ tự mình tìm ra nó.

Nhưng tuy nhiên vẫn có một số khó khăn. Ví dụ: thực tế là IN với truy vấn con không sử dụng chỉ mục. Nhưng đây là vấn đề của chúng tôi và chúng tôi cần phải khắc phục nó. Không có gì cơ bản ở đây. Chúng tôi sẽ sửa nó*.

Và một điều thú vị nữa là nếu bạn có một yêu cầu rất dài và quá trình xử lý yêu cầu phân tán đang diễn ra thì yêu cầu rất dài này sẽ được gửi đến từng máy chủ mà không cần nén. Ví dụ: 100 megabyte và 500 máy chủ. Và theo đó, bạn sẽ có 50 gigabyte được truyền qua mạng. Nó sẽ được truyền đi và sau đó mọi thứ sẽ được hoàn thành thành công.

* đã sử dụng; Mọi thứ đã được sửa chữa như đã hứa.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Và một trường hợp khá phổ biến là khi các yêu cầu đến từ API. Ví dụ: bạn đã tạo một số loại dịch vụ của riêng mình. Và nếu ai đó cần dịch vụ của bạn, thì bạn mở API và đúng hai ngày sau, bạn sẽ thấy điều gì đó không thể hiểu được đang xảy ra. Mọi thứ đều quá tải và một số yêu cầu khủng khiếp đang đến mà lẽ ra không bao giờ nên xảy ra.

Và chỉ có một giải pháp. Nếu bạn đã mở API thì bạn sẽ phải cắt nó đi. Ví dụ, đưa ra một số loại hạn ngạch. Không có lựa chọn bình thường nào khác. Nếu không, họ sẽ viết kịch bản ngay và sẽ có vấn đề.

Và ClickHouse có một tính năng đặc biệt - tính hạn ngạch. Hơn nữa, bạn có thể chuyển khóa hạn ngạch của mình. Ví dụ: đây là ID người dùng nội bộ. Và hạn ngạch sẽ được tính toán độc lập cho từng người trong số họ.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Bây giờ là một điều thú vị khác. Đây là sự sao chép thủ công.

Tôi biết nhiều trường hợp, mặc dù ClickHouse có hỗ trợ sao chép tích hợp nhưng mọi người vẫn sao chép ClickHouse theo cách thủ công.

Nguyên tắc là gì? Bạn có một đường dẫn xử lý dữ liệu. Và nó hoạt động độc lập, chẳng hạn như ở các trung tâm dữ liệu khác nhau. Bạn viết cùng một dữ liệu theo cách tương tự trong ClickHouse. Đúng, thực tế cho thấy dữ liệu sẽ vẫn phân kỳ do một số tính năng trong mã của bạn. Tôi hy vọng nó ở trong bạn.

Và đôi khi bạn vẫn sẽ phải đồng bộ thủ công. Ví dụ: mỗi tháng một lần quản trị viên thực hiện rsync.

Trên thực tế, việc sử dụng bản sao được tích hợp trong ClickHouse sẽ dễ dàng hơn nhiều. Nhưng có thể có một số chống chỉ định, vì để làm được điều này bạn cần sử dụng ZooKeeper. Tôi sẽ không nói bất cứ điều gì xấu về ZooKeeper, về nguyên tắc, hệ thống này hoạt động, nhưng có trường hợp mọi người không sử dụng nó vì sợ java, bởi vì ClickHouse là một hệ thống tốt, được viết bằng C++, bạn có thể sử dụng và mọi thứ sẽ ổn thôi. Và ZooKeeper có trong java. Và bằng cách nào đó bạn thậm chí không muốn nhìn, nhưng sau đó bạn có thể sử dụng tính năng sao chép thủ công.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

ClickHouse là một hệ thống thực tế. Cô ấy tính đến nhu cầu của bạn. Nếu có bản sao thủ công thì bạn có thể tạo bảng Phân phối để xem xét các bản sao thủ công và thực hiện chuyển đổi dự phòng giữa chúng. Và thậm chí còn có một tùy chọn đặc biệt cho phép bạn tránh thất bại, ngay cả khi các đường của bạn phân kỳ một cách có hệ thống.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Các vấn đề khác có thể phát sinh nếu bạn sử dụng các công cụ bảng nguyên thủy. ClickHouse là một công cụ xây dựng có nhiều công cụ tạo bảng khác nhau. Đối với tất cả các trường hợp nghiêm trọng, như được viết trong tài liệu, hãy sử dụng các bảng từ dòng MergeTree. Và tất cả phần còn lại - điều này là như vậy đối với từng trường hợp riêng lẻ hoặc đối với các bài kiểm tra.

Trong bảng MergeTree, bạn không cần phải có bất kỳ ngày và giờ nào. Bạn vẫn có thể sử dụng nó. Nếu không có ngày giờ thì ghi mặc định là 2000. Điều này sẽ hoạt động và sẽ không yêu cầu tài nguyên.

Và trong phiên bản mới của máy chủ, bạn thậm chí có thể chỉ định rằng bạn có phân vùng tùy chỉnh mà không cần khóa phân vùng. Nó sẽ giống nhau.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Mặt khác, bạn có thể sử dụng các công cụ bảng nguyên thủy. Ví dụ: điền dữ liệu một lần và xem, vặn và xóa. Bạn có thể sử dụng Nhật ký.

Hoặc lưu trữ khối lượng nhỏ để xử lý trung gian là StripeLog hoặc TinyLog.

Bộ nhớ có thể được sử dụng nếu lượng dữ liệu nhỏ và bạn có thể chỉ cần xoay thứ gì đó trong RAM.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

ClickHouse không thực sự thích dữ liệu được chuẩn hóa lại.

Đây là một ví dụ điển hình. Đây là một số lượng lớn các URL. Bạn đặt chúng vào bảng tiếp theo. Và sau đó họ quyết định THAM GIA với họ, nhưng điều này sẽ không hiệu quả, theo quy định, vì ClickHouse chỉ hỗ trợ Hash THAM GIA. Nếu không đủ RAM cho nhiều dữ liệu cần kết nối thì JOIN sẽ không hoạt động*.

Nếu dữ liệu có lượng số cao thì đừng lo lắng, hãy lưu trữ dữ liệu ở dạng không chuẩn hóa, các URL được đặt trực tiếp trong bảng chính.

* và hiện tại ClickHouse cũng có tính năng kết hợp hợp nhất và nó hoạt động trong điều kiện dữ liệu trung gian không vừa với RAM. Nhưng điều này không hiệu quả và khuyến nghị vẫn có hiệu lực.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Một vài ví dụ nữa, nhưng tôi đã nghi ngờ liệu chúng có phải là phản mẫu hay không.

ClickHouse có một lỗ hổng đã biết. Nó không biết cách cập nhật*. Ở một khía cạnh nào đó, điều này thậm chí còn tốt. Nếu bạn có một số dữ liệu quan trọng, chẳng hạn như kế toán, thì sẽ không ai có thể gửi nó vì không có bản cập nhật.

* hỗ trợ cập nhật và xóa ở chế độ hàng loạt đã được thêm vào từ lâu.

Nhưng có một số cách đặc biệt cho phép cập nhật như thể ở chế độ nền. Ví dụ: các bảng như RestoreMergeTree. Họ thực hiện cập nhật trong quá trình hợp nhất nền. Bạn có thể buộc điều này bằng cách sử dụng bảng tối ưu hóa. Nhưng đừng làm điều này quá thường xuyên vì nó sẽ ghi đè hoàn toàn lên phân vùng.

Các THAM GIA được phân phối trong ClickHouse cũng được trình lập kế hoạch truy vấn xử lý kém.

Xấu, nhưng đôi khi Ok.

Chỉ sử dụng ClickHouse để đọc lại dữ liệu bằng cách sử dụng select*.

Tôi không khuyên bạn nên sử dụng ClickHouse để tính toán rườm rà. Nhưng điều này không hoàn toàn đúng vì chúng tôi đã rời bỏ khuyến nghị này. Và gần đây chúng tôi đã bổ sung thêm khả năng áp dụng các mô hình học máy trong ClickHouse - Catboost. Và điều đó làm tôi khó chịu vì tôi nghĩ, “Thật là kinh khủng. Đây là số chu kỳ trên mỗi byte! Tôi thực sự ghét lãng phí đồng hồ theo byte.

Sử dụng ClickHouse hiệu quả. Alexey Milovidov (Yandex)

Nhưng đừng sợ, hãy cài đặt ClickHouse, mọi thứ sẽ ổn thôi. Nếu có bất cứ điều gì, chúng tôi có một cộng đồng. Nhân tiện, cộng đồng là bạn. Và nếu bạn gặp bất kỳ vấn đề nào, ít nhất bạn có thể truy cập cuộc trò chuyện của chúng tôi và hy vọng họ sẽ giúp bạn.

câu hỏi

Cảm ơn vì đã báo cáo! Tôi có thể khiếu nại về lỗi ClickHouse ở đâu?

Bạn có thể khiếu nại với cá nhân tôi ngay bây giờ.

Gần đây tôi đã bắt đầu sử dụng ClickHouse. Tôi ngay lập tức bỏ giao diện cli.

Bạn thật may mắn.

Một lát sau, tôi đã làm hỏng máy chủ chỉ với một lựa chọn nhỏ.

Bạn có tài năng.

Tôi đã mở một lỗi GitHub nhưng nó đã bị bỏ qua.

Chúng ta sẽ thấy.

Alexey lừa tôi tham dự buổi báo cáo, hứa sẽ cho tôi biết cách truy cập dữ liệu bên trong.

Rất đơn giản.

Tôi đã nhận ra điều này ngày hôm qua. Thêm chi tiết cụ thể.

Không có thủ thuật khủng khiếp nào ở đó. Chỉ có nén theo từng khối. Mặc định là LZ4, bạn có thể bật ZSTD*. Khối từ 64 kilobyte đến 1 megabyte.

* cũng có hỗ trợ cho các codec nén chuyên dụng có thể được sử dụng trong chuỗi với các thuật toán khác.

Các khối chỉ là dữ liệu thô?

Không hoàn toàn thô. Có mảng. Nếu bạn có một cột số thì các số trong một hàng sẽ được đặt trong một mảng.

Rõ ràng.

Alexey, một ví dụ về uniqExact qua IP, tức là thực tế là uniqExact mất nhiều thời gian hơn để tính toán theo dòng so với tính toán theo số, v.v. Điều gì sẽ xảy ra nếu chúng ta sử dụng đòn nhử bằng tai và niệm phép vào thời điểm hiệu đính? Tức là, có vẻ như bạn đã nói rằng trên đĩa của chúng tôi, nó không khác lắm. Nếu chúng ta đọc các dòng từ đĩa và truyền, liệu tập hợp của chúng ta có nhanh hơn hay không? Hay chúng ta vẫn sẽ đạt được một chút ở đây? Đối với tôi, có vẻ như bạn đã thử nghiệm điều này, nhưng vì lý do nào đó không chỉ ra nó trong điểm chuẩn.

Tôi nghĩ nó sẽ chậm hơn so với việc không truyền. Trong trường hợp này, địa chỉ IP phải được phân tích cú pháp từ chuỗi. Tất nhiên, tại ClickHouse, việc phân tích địa chỉ IP của chúng tôi cũng được tối ưu hóa. Chúng tôi đã cố gắng rất nhiều nhưng ở đó bạn có những con số được viết ở dạng thứ mười nghìn. Rất không thoải mái. Mặt khác, hàm uniqExact sẽ hoạt động chậm hơn trên các chuỗi, không chỉ vì đây là các chuỗi mà còn vì một chuyên môn khác của thuật toán được chọn. Chuỗi đơn giản được xử lý khác nhau.

Điều gì sẽ xảy ra nếu chúng ta lấy một kiểu dữ liệu nguyên thủy hơn? Ví dụ, chúng ta viết id người dùng mà chúng ta có, viết thành một dòng rồi xáo trộn, liệu nó có vui hơn hay không?

Tôi nghi ngờ. Tôi nghĩ sẽ còn buồn hơn nữa, vì suy cho cùng, việc phân tích các con số là một vấn đề nghiêm trọng. Đối với tôi, có vẻ như đồng nghiệp này thậm chí còn đưa ra một báo cáo về việc phân tích các số ở dạng thứ mười nghìn khó đến mức nào, nhưng có lẽ là không.

Alexey, cảm ơn bạn rất nhiều vì đã báo cáo! Và cảm ơn ClickHouse rất nhiều! Tôi có một câu hỏi về kế hoạch. Có kế hoạch nào cho tính năng cập nhật từ điển không đầy đủ không?

Tức là khởi động lại một phần?

Vâng vâng. Giống như khả năng thiết lập trường MySQL ở đó, tức là cập nhật sau để chỉ dữ liệu này được tải nếu từ điển rất lớn.

Một tính năng rất thú vị. Và tôi nghĩ ai đó đã đề xuất nó trong cuộc trò chuyện của chúng tôi. Có lẽ đó thậm chí là bạn.

Tôi không nghĩ vậy.

Tuyệt vời, bây giờ hóa ra có hai yêu cầu. Và bạn có thể từ từ bắt đầu thực hiện nó. Nhưng tôi muốn cảnh báo ngay với bạn rằng tính năng này khá đơn giản để thực hiện. Tức là về lý thuyết bạn chỉ cần ghi số phiên bản vào bảng rồi viết: version less than such và such. Điều này có nghĩa là rất có thể chúng tôi sẽ cung cấp tính năng này cho những người đam mê. Bạn có phải là người đam mê?

Có, nhưng thật không may, không có trong C++.

Đồng nghiệp của bạn có biết viết bằng C++ không?

Tôi sẽ tìm ai đó.

Tuyệt vời*.

* tính năng này đã được thêm vào hai tháng sau báo cáo - tác giả của câu hỏi đã phát triển nó và gửi câu hỏi của mình yêu cầu kéo.

Cảm ơn bạn!

Xin chào! Cảm ơn vì đã báo cáo! Bạn đã đề cập rằng ClickHouse rất giỏi trong việc tiêu thụ tất cả các tài nguyên có sẵn cho nó. Và diễn giả bên cạnh Luxoft đã nói về giải pháp của ông cho Bưu điện Nga. Anh ấy nói rằng họ thực sự thích ClickHouse, nhưng họ không sử dụng nó thay vì đối thủ cạnh tranh chính vì nó ngốn hết CPU. Và họ không thể cắm nó vào kiến ​​trúc của họ, vào ZooKeeper bằng các đế cắm. Có thể bằng cách nào đó hạn chế ClickHouse để nó không tiêu thụ mọi thứ có sẵn cho nó không?

Vâng, điều đó là có thể và rất dễ dàng. Nếu bạn muốn tiêu thụ ít lõi hơn thì chỉ cần viết set max_threads = 1. Và thế là xong, nó sẽ thực thi yêu cầu trong một lõi. Hơn nữa, bạn có thể chỉ định các cài đặt khác nhau cho những người dùng khác nhau. Vì vậy không có vấn đề gì. Và hãy nói với đồng nghiệp của bạn ở Luxoft rằng thật không tốt khi họ không tìm thấy cài đặt này trong tài liệu.

Alexey, xin chào! Tôi muốn hỏi về câu hỏi này. Đây không phải là lần đầu tiên tôi nghe nói rằng nhiều người bắt đầu sử dụng ClickHouse làm nơi lưu trữ nhật ký. Trong báo cáo bạn đã nói không làm điều này, tức là bạn không cần lưu trữ các chuỗi dài. Bạn nghĩ gì về nó?

Thứ nhất, nhật ký thường không phải là chuỗi dài. Tất nhiên có sự ngoại lệ. Ví dụ: một số dịch vụ được viết bằng java đưa ra một ngoại lệ, nó sẽ được ghi lại. Và cứ như vậy trong một vòng lặp vô tận, và dung lượng trên ổ cứng cạn kiệt. Giải pháp này rất đơn giản. Nếu các dòng rất dài thì hãy cắt chúng. dài nghĩa là gì? Hàng chục kilobyte là không tốt*.

* trong các phiên bản mới nhất của ClickHouse, “mức độ chi tiết của chỉ mục thích ứng” được bật, giúp loại bỏ hầu hết vấn đề lưu trữ các hàng dài.

Một kilobyte có bình thường không?

Là bình thường

Xin chào! Cảm ơn vì đã báo cáo! Tôi đã hỏi về vấn đề này trong cuộc trò chuyện nhưng tôi không nhớ mình đã nhận được câu trả lời hay chưa. Có kế hoạch nào đó để mở rộng phần VỚI theo cách của CTE không?

Chưa. Phần VỚI của chúng tôi có phần phù phiếm. Nó giống như một tính năng nhỏ đối với chúng tôi.

Tôi hiểu. Cảm ơn!

Cảm ơn vì đã báo cáo! Rất thú vị! Câu hỏi toàn cầu. Có kế hoạch nào để sửa đổi việc xóa dữ liệu không, có thể dưới dạng một số loại sơ khai?

Cần thiết. Đây là nhiệm vụ đầu tiên trong hàng đợi của chúng tôi. Hiện chúng tôi đang tích cực suy nghĩ về cách thực hiện mọi thứ một cách chính xác. Và bạn nên bắt đầu nhấn bàn phím*.

* nhấn các nút trên bàn phím và làm mọi thứ.

Điều này bằng cách nào đó có ảnh hưởng đến hiệu suất hệ thống hay không? Liệu việc chèn có nhanh như bây giờ không?

Có lẽ bản thân việc xóa và bản thân các bản cập nhật sẽ rất nặng, nhưng điều này sẽ không ảnh hưởng đến hiệu suất của các lựa chọn hoặc hiệu suất của các phần chèn.

Và một câu hỏi nhỏ nữa. Tại phần trình bày bạn đã nói về khóa chính. Theo đó, chúng ta có phân vùng mặc định hàng tháng phải không? Và khi chúng ta đặt phạm vi ngày phù hợp với một tháng thì chỉ phân vùng này được đọc, phải không?

Vâng.

Một câu hỏi. Nếu chúng tôi không thể chọn bất kỳ khóa chính nào, thì có đúng không khi thực hiện cụ thể theo trường “Ngày” để dữ liệu này ít được sắp xếp lại trong nền để phù hợp với trật tự hơn? Nếu bạn không có truy vấn phạm vi và thậm chí bạn không thể chọn bất kỳ khóa chính nào, thì việc đặt ngày vào khóa chính có đáng không?

Vâng.

Có lẽ sẽ hợp lý hơn nếu đặt một trường vào khóa chính để nén dữ liệu tốt hơn nếu nó được sắp xếp theo trường này. Ví dụ: ID người dùng. Ví dụ: người dùng truy cập vào cùng một trang web. Trong trường hợp này, hãy đặt id người dùng và thời gian. Và khi đó dữ liệu của bạn sẽ được nén tốt hơn. Về ngày, nếu bạn thực sự không có và không bao giờ có truy vấn phạm vi về ngày, thì bạn không cần phải nhập ngày vào khóa chính.

OK cảm ơn bạn rất nhiều!

Nguồn: www.habr.com

Thêm một lời nhận xét