Cách nhìn vào mắt Cassandra mà không làm mất dữ liệu, sự ổn định và niềm tin vào NoSQL

Cách nhìn vào mắt Cassandra mà không làm mất dữ liệu, sự ổn định và niềm tin vào NoSQL

Người ta nói rằng mọi thứ trong đời đều đáng để thử ít nhất một lần. Và nếu bạn đã quen làm việc với các DBMS quan hệ, thì bạn nên làm quen với NoSQL trong thực tế, trước hết, ít nhất là để phát triển chung. Hiện nay, do sự phát triển nhanh chóng của công nghệ này, có rất nhiều ý kiến ​​​​trái chiều và tranh luận sôi nổi về chủ đề này, điều này đặc biệt thu hút sự quan tâm.
Nếu đi sâu vào bản chất của tất cả những tranh chấp này, bạn có thể thấy rằng chúng phát sinh do cách tiếp cận sai lầm. Những người sử dụng cơ sở dữ liệu NoSQL chính xác ở những nơi cần thiết đều hài lòng và nhận được tất cả lợi ích từ giải pháp này. Và những người thử nghiệm dựa vào công nghệ này như một loại thuốc chữa bách bệnh mà nó hoàn toàn không thể áp dụng được đều thất vọng vì đã đánh mất sức mạnh của cơ sở dữ liệu quan hệ mà không thu được lợi ích đáng kể.

Tôi sẽ kể cho bạn nghe về kinh nghiệm của chúng tôi trong việc triển khai giải pháp dựa trên Cassandra DBMS: những gì chúng tôi phải đối mặt, cách chúng tôi thoát khỏi những tình huống khó khăn, liệu chúng tôi có thể hưởng lợi từ việc sử dụng NoSQL hay không và chúng tôi phải đầu tư thêm nỗ lực/kinh phí vào đâu .
Nhiệm vụ ban đầu là xây dựng một hệ thống ghi lại các cuộc gọi trong một số loại lưu trữ.

Nguyên lý hoạt động của hệ thống như sau. Đầu vào bao gồm các tệp có cấu trúc cụ thể mô tả cấu trúc của cuộc gọi. Sau đó, ứng dụng sẽ đảm bảo rằng cấu trúc này được lưu trữ trong các cột thích hợp. Sau này, các cuộc gọi đã lưu sẽ được dùng để hiển thị thông tin về mức tiêu thụ lưu lượng của thuê bao (cước phí, cuộc gọi, lịch sử số dư).

Cách nhìn vào mắt Cassandra mà không làm mất dữ liệu, sự ổn định và niềm tin vào NoSQL

Khá rõ ràng lý do tại sao họ chọn Cassandra - cô ấy viết như một khẩu súng máy, có khả năng mở rộng dễ dàng và có khả năng chịu lỗi.

Vì vậy, đây là những gì kinh nghiệm đã cho chúng tôi

Đúng, một nút bị lỗi không phải là một bi kịch. Đây là bản chất của khả năng chịu lỗi của Cassandra. Nhưng một nút có thể còn sống và đồng thời bắt đầu bị ảnh hưởng về hiệu suất. Hóa ra, điều này ngay lập tức ảnh hưởng đến hiệu suất của toàn bộ cụm.

Cassandra sẽ không bảo vệ bạn khi Oracle đã cứu bạn bằng những ràng buộc của nó. Và nếu tác giả của ứng dụng không hiểu trước điều này, thì bản nhân đôi đến với Cassandra cũng không tệ hơn bản gốc. Khi nó đến, chúng tôi sẽ đưa nó vào.

IB thực sự không thích Cassandra miễn phí: Không ghi nhật ký hành động của người dùng, không phân biệt quyền. Thông tin về các cuộc gọi được coi là dữ liệu cá nhân, có nghĩa là mọi nỗ lực yêu cầu/thay đổi thông tin đó theo bất kỳ cách nào đều phải được ghi lại với khả năng kiểm tra tiếp theo. Ngoài ra, bạn cần nhận thức được sự cần thiết phải phân chia quyền ở các cấp độ khác nhau cho những người dùng khác nhau. Một kỹ sư vận hành đơn giản và một quản trị viên cấp cao có thể tự do xóa toàn bộ không gian phím có những vai trò, trách nhiệm và năng lực khác nhau. Nếu không có sự phân biệt quyền truy cập như vậy, giá trị và tính toàn vẹn của dữ liệu sẽ ngay lập tức bị nghi ngờ nhanh hơn so với BẤT KỲ mức độ nhất quán nào.

Chúng tôi đã không tính đến việc các cuộc gọi yêu cầu cả phân tích nghiêm túc và lấy mẫu định kỳ cho nhiều điều kiện khác nhau. Vì các bản ghi đã chọn sau đó sẽ bị xóa và ghi lại (như một phần của nhiệm vụ, chúng tôi phải hỗ trợ quá trình cập nhật dữ liệu khi dữ liệu ban đầu được nhập vào vòng lặp của chúng tôi không chính xác), Cassandra không phải là bạn của chúng tôi ở đây. Cassandra giống như một con heo đất - bỏ đồ vào thì tiện nhưng không thể đếm được.

Chúng tôi gặp sự cố khi truyền dữ liệu đến vùng thử nghiệm (5 nút trong thử nghiệm so với 20 nút trong buổi dạ hội). Trong trường hợp này, kết xuất không thể được sử dụng.

Sự cố khi cập nhật lược đồ dữ liệu của ứng dụng ghi vào Cassandra. Việc khôi phục sẽ tạo ra rất nhiều bia mộ, điều này có thể dẫn đến tổn thất năng suất theo những cách không thể đoán trước.. Cassandra được tối ưu hóa cho việc ghi và không cần suy nghĩ nhiều trước khi ghi, bất kỳ thao tác nào với dữ liệu hiện có trong đó cũng là bản ghi. Nghĩa là, bằng cách xóa những thứ không cần thiết, chúng tôi sẽ chỉ tạo ra nhiều bản ghi hơn nữa và chỉ một số bản ghi trong số đó sẽ được đánh dấu bằng bia mộ.

Hết thời gian chờ khi chèn. Cassandra rất đẹp trong đoạn ghi âm, nhưng đôi khi dòng chảy đến có thể khiến cô ấy bối rối một cách đáng kể. Điều này xảy ra khi ứng dụng bắt đầu xoay quanh một số bản ghi không thể chèn được vì lý do nào đó. Và chúng tôi sẽ cần một DBA thực sự, người sẽ giám sát gc.log, nhật ký hệ thống và gỡ lỗi để tìm các truy vấn chậm, số liệu về quá trình nén đang chờ xử lý.

Một số trung tâm dữ liệu trong một cụm. Đọc từ đâu và viết ở đâu?
Có lẽ chia thành đọc và viết? Và nếu vậy thì có nên có DC gần ứng dụng để viết hoặc đọc hơn không? Và chẳng phải chúng ta sẽ có một bộ não thực sự bị chia rẽ nếu chọn sai mức độ nhất quán sao? Có rất nhiều câu hỏi, rất nhiều cài đặt chưa biết, rất nhiều khả năng mà bạn thực sự muốn mày mò.

Chúng tôi đã quyết định như thế nào

Để ngăn nút chìm, SWAP đã bị tắt. Và bây giờ, nếu thiếu bộ nhớ, nút sẽ ngừng hoạt động và không tạo ra các khoảng dừng gc lớn.

Vì vậy, chúng tôi không còn dựa vào logic trong cơ sở dữ liệu nữa. Các nhà phát triển ứng dụng đang tự đào tạo lại và bắt đầu tích cực thực hiện các biện pháp phòng ngừa trong mã của riêng họ. Lý tưởng tách biệt rõ ràng việc lưu trữ và xử lý dữ liệu.

Chúng tôi đã mua hỗ trợ từ DataStax. Sự phát triển của Cassandra đóng hộp đã chấm dứt (cam kết cuối cùng là vào tháng 2018 năm XNUMX). Đồng thời, Datastax cung cấp dịch vụ xuất sắc và một số lượng lớn các giải pháp được sửa đổi và điều chỉnh cho các giải pháp IP hiện có.

Tôi cũng muốn lưu ý rằng Cassandra không thuận tiện lắm cho việc lựa chọn truy vấn. Tất nhiên, CQL là một bước tiến lớn của người dùng (so với Trift). Nhưng nếu bạn có toàn bộ các bộ phận đã quen với việc kết nối thuận tiện như vậy, lọc miễn phí theo bất kỳ trường nào và khả năng tối ưu hóa truy vấn, đồng thời các bộ phận này đang nỗ lực giải quyết các khiếu nại và sự cố, thì giải pháp trên Cassandra có vẻ thù địch và ngu ngốc đối với họ. Và chúng tôi bắt đầu quyết định cách các đồng nghiệp của mình nên tạo mẫu.

Chúng tôi đã xem xét hai tùy chọn. Trong tùy chọn đầu tiên, chúng tôi viết các lệnh gọi không chỉ trong C* mà còn trong cơ sở dữ liệu Oracle đã lưu trữ. Chỉ có điều, không giống như C*, cơ sở dữ liệu này chỉ lưu trữ các cuộc gọi trong tháng hiện tại (đủ độ sâu lưu trữ cuộc gọi cho các trường hợp sạc lại). Ở đây, chúng tôi thấy ngay vấn đề sau: nếu chúng tôi viết đồng bộ, thì chúng tôi sẽ mất tất cả các ưu điểm của C* liên quan đến tính năng chèn nhanh; nếu chúng tôi viết không đồng bộ, không có gì đảm bảo rằng tất cả các cuộc gọi cần thiết đều vào được Oracle. Có một điểm cộng, nhưng là một điểm cộng lớn: để vận hành vẫn sử dụng PL/SQL Developer quen thuộc, tức là chúng tôi triển khai mẫu “Facade” trên thực tế. Chúng tôi triển khai cơ chế loại bỏ các cuộc gọi từ C*, lấy một số dữ liệu để làm phong phú từ các bảng tương ứng trong Oracle, nối các mẫu kết quả và cung cấp cho chúng tôi kết quả mà sau đó chúng tôi sử dụng bằng cách nào đó (quay lại, lặp lại, phân tích, ngưỡng mộ). Nhược điểm: quy trình khá nhiều bước và ngoài ra không có giao diện cho nhân viên vận hành.

Cuối cùng, chúng tôi quyết định lựa chọn thứ hai. Apache Spark đã được sử dụng để lấy mẫu từ các lọ khác nhau. Bản chất của cơ chế này đã được rút gọn thành mã Java, mã này sử dụng các khóa được chỉ định (người đăng ký, thời gian gọi - khóa phần), lấy dữ liệu từ C*, cũng như dữ liệu cần thiết để làm phong phú từ bất kỳ cơ sở dữ liệu nào khác. Sau đó, nó nối chúng vào bộ nhớ và hiển thị kết quả trong bảng kết quả. Chúng tôi đã vẽ một mặt web lên trên tia lửa và hóa ra nó khá hữu dụng.

Cách nhìn vào mắt Cassandra mà không làm mất dữ liệu, sự ổn định và niềm tin vào NoSQL

Khi giải quyết vấn đề cập nhật dữ liệu thử nghiệm công nghiệp, chúng tôi lại xem xét một số giải pháp. Cả hai đều chuyển qua Sstloader và tùy chọn chia cụm trong vùng thử nghiệm thành hai phần, mỗi phần luân phiên thuộc cùng một cụm với cụm quảng cáo, do đó được cung cấp bởi nó. Khi cập nhật thử nghiệm, người ta đã lên kế hoạch hoán đổi chúng: phần hoạt động trong thử nghiệm sẽ bị xóa và đưa vào sản xuất, phần còn lại bắt đầu hoạt động với dữ liệu riêng biệt. Tuy nhiên, sau khi suy nghĩ lại, chúng tôi đã đánh giá hợp lý hơn dữ liệu đáng chuyển và nhận ra rằng bản thân các cuộc gọi là một thực thể không nhất quán để thử nghiệm, được tạo nhanh chóng nếu cần và đó là tập dữ liệu quảng cáo không có giá trị để chuyển sang Bài kiểm tra. Có một số đồ vật lưu trữ đáng để di chuyển, nhưng đây thực sự là một vài chiếc bàn và không nặng lắm. Vì vậy chúng tôi Như một giải pháp, Spark lại ra tay giải cứu, với sự trợ giúp của nó, chúng tôi đã viết và bắt đầu tích cực sử dụng tập lệnh để truyền dữ liệu giữa các bảng, thử nghiệm quảng cáo.

Chính sách triển khai hiện tại của chúng tôi cho phép chúng tôi làm việc mà không cần khôi phục. Trước chương trình khuyến mãi, có một cuộc chạy thử bắt buộc, trong đó sai sót không quá đắt. Trong trường hợp thất bại, bạn luôn có thể bỏ casespace và cuộn toàn bộ sơ đồ lại từ đầu.

Để đảm bảo Cassandra có sẵn liên tục, bạn cần một dba chứ không chỉ anh ta. Mọi người làm việc với ứng dụng phải hiểu vị trí và cách xem xét tình hình hiện tại cũng như cách chẩn đoán vấn đề kịp thời. Để thực hiện điều này, chúng tôi tích cực sử dụng DataStax OpsCenter (Quản trị và giám sát khối lượng công việc), số liệu hệ thống Trình điều khiển Cassandra (số lần hết thời gian chờ để ghi vào C*, số lần hết thời gian chờ để đọc từ C*, độ trễ tối đa, v.v.), giám sát hoạt động của chính ứng dụng đó, làm việc với Cassandra.

Khi nghĩ về câu hỏi trước, chúng tôi nhận ra rủi ro chính của chúng tôi có thể nằm ở đâu. Đây là các biểu mẫu hiển thị dữ liệu hiển thị dữ liệu từ một số truy vấn độc lập tới bộ lưu trữ. Bằng cách này chúng ta có thể nhận được thông tin khá không nhất quán. Nhưng vấn đề này sẽ có liên quan nếu chúng ta chỉ làm việc với một trung tâm dữ liệu. Vì vậy, điều hợp lý nhất ở đây tất nhiên là tạo một hàm hàng loạt để đọc dữ liệu trên ứng dụng của bên thứ ba, điều này sẽ đảm bảo rằng dữ liệu được nhận trong một khoảng thời gian duy nhất. Đối với việc phân chia thành đọc và viết về mặt hiệu suất, ở đây chúng tôi đã dừng lại bởi nguy cơ mất kết nối giữa các DC, chúng tôi có thể tạo ra hai cụm hoàn toàn không nhất quán với nhau.

Kết quả là, hiện tại dừng ở mức nhất quán để ghi EACH_QUORUM, để đọc - LOCAL_QUORUM

Ấn tượng và kết luận ngắn gọn

Để đánh giá giải pháp đạt được từ quan điểm hỗ trợ hoạt động và triển vọng phát triển hơn nữa, chúng tôi quyết định suy nghĩ xem sự phát triển như vậy có thể được áp dụng ở đâu khác.

Ngay lập tức, sau đó chấm điểm dữ liệu cho các chương trình như “Thanh toán khi thuận tiện” (chúng tôi tải thông tin vào C*, tính toán bằng tập lệnh Spark), tính toán các xác nhận quyền sở hữu bằng cách tổng hợp theo khu vực, lưu trữ vai trò và tính toán quyền truy cập của người dùng dựa trên vai trò ma trận.

Như bạn có thể thấy, các tiết mục rất phong phú và đa dạng. Và nếu chúng tôi chọn phe ủng hộ/phản đối NoSQL, thì chúng tôi sẽ tham gia cùng những người ủng hộ, vì chúng tôi đã nhận được lợi thế của mình và chính xác ở nơi chúng tôi mong đợi.

Ngay cả tùy chọn Cassandra sẵn có cũng cho phép chia tỷ lệ theo chiều ngang trong thời gian thực, giải quyết hoàn toàn dễ dàng vấn đề tăng dữ liệu trong hệ thống. Chúng tôi đã có thể di chuyển một cơ chế tải rất cao để tính toán tổng hợp cuộc gọi thành một mạch riêng biệt, đồng thời tách biệt lược đồ và logic ứng dụng, loại bỏ thói quen xấu là viết các công việc và đối tượng tùy chỉnh trong chính cơ sở dữ liệu. Chúng tôi có cơ hội lựa chọn và định cấu hình, tăng tốc, những DC nào chúng tôi sẽ thực hiện tính toán và những DC nào chúng tôi sẽ ghi lại dữ liệu, chúng tôi tự bảo hiểm mình trước sự cố của cả các nút riêng lẻ và toàn bộ DC.

Áp dụng kiến ​​​​trúc của chúng tôi vào các dự án mới và đã có một số kinh nghiệm, tôi muốn tính đến ngay các sắc thái được mô tả ở trên và ngăn ngừa một số sai sót, làm phẳng một số góc nhọn mà ban đầu không thể tránh được.

Ví dụ, theo dõi các cập nhật của Cassandra một cách kịp thờibởi vì khá nhiều vấn đề chúng tôi gặp phải đã được biết và khắc phục.

Không đặt cả cơ sở dữ liệu và Spark trên cùng một nút (hoặc chia chặt chẽ cho lượng sử dụng tài nguyên cho phép), vì Spark có thể ăn nhiều OP hơn dự kiến ​​và chúng ta sẽ nhanh chóng gặp vấn đề số 1 trong danh sách của mình.

Nâng cao năng lực giám sát và vận hành ở giai đoạn thử nghiệm dự án. Ban đầu, hãy tính đến tất cả người tiêu dùng tiềm năng của giải pháp của chúng tôi càng nhiều càng tốt, bởi vì đây chính là thứ mà cấu trúc cơ sở dữ liệu cuối cùng sẽ phụ thuộc vào.

Xoay mạch kết quả nhiều lần để có thể tối ưu hóa. Chọn trường nào có thể được tuần tự hóa. Hiểu những bảng bổ sung nào chúng tôi nên tạo để tính đến một cách chính xác và tối ưu nhất, sau đó cung cấp thông tin cần thiết theo yêu cầu (ví dụ: bằng cách giả định rằng chúng tôi có thể lưu trữ cùng một dữ liệu trong các bảng khác nhau, có tính đến các phân tích khác nhau theo tiêu chí khác nhau, chúng ta có thể tiết kiệm đáng kể thời gian CPU cho các yêu cầu đọc).

Không tệ Cung cấp ngay việc đính kèm TTL và làm sạch dữ liệu lỗi thời.

Khi tải dữ liệu từ Cassandra Logic ứng dụng phải hoạt động theo nguyên tắc FETCH, sao cho không phải tất cả các hàng đều được tải vào bộ nhớ cùng một lúc mà được chọn theo đợt.

Nên chuyển dự án sang giải pháp được mô tả trước khi chuyển kiểm tra khả năng chịu lỗi của hệ thống bằng cách tiến hành một loạt thử nghiệm va chạm, chẳng hạn như mất dữ liệu trong một trung tâm dữ liệu, khôi phục dữ liệu bị hỏng trong một khoảng thời gian nhất định, mất mạng giữa các trung tâm dữ liệu. Các thử nghiệm như vậy sẽ không chỉ cho phép người ta đánh giá ưu và nhược điểm của kiến ​​trúc được đề xuất mà còn cung cấp phương pháp khởi động tốt cho các kỹ sư thực hiện chúng và kỹ năng thu được sẽ không còn thừa nếu lỗi hệ thống được tái hiện trong quá trình sản xuất.

Nếu chúng ta làm việc với thông tin quan trọng (chẳng hạn như dữ liệu thanh toán, tính nợ thuê bao), thì cũng cần chú ý đến các công cụ giúp giảm thiểu rủi ro phát sinh do các tính năng của DBMS. Ví dụ: sử dụng tiện ích nodesync (Datastax), đã phát triển một chiến lược tối ưu cho việc sử dụng nó để vì mục đích nhất quán, không tạo ra tải quá mức cho Cassandra và chỉ sử dụng nó cho một số bảng nhất định trong một khoảng thời gian nhất định.

Điều gì xảy ra với Cassandra sau sáu tháng sống? Nói chung là không có vấn đề gì chưa giải quyết được. Chúng tôi cũng không cho phép xảy ra bất kỳ tai nạn nghiêm trọng hoặc mất dữ liệu nào. Đúng, chúng tôi đã phải nghĩ đến việc bù đắp cho một số vấn đề chưa phát sinh trước đó, nhưng cuối cùng thì điều này không ảnh hưởng nhiều đến giải pháp kiến ​​trúc của chúng tôi. Nếu bạn muốn và không ngại thử điều gì đó mới, đồng thời không muốn quá thất vọng, thì hãy sẵn sàng cho sự thật rằng không có gì là miễn phí. Bạn sẽ phải hiểu, đi sâu vào tài liệu và lắp ráp chiếc cào của riêng mình nhiều hơn so với giải pháp cũ và không có lý thuyết nào cho bạn biết trước chiếc cào nào đang chờ bạn.

Nguồn: www.habr.com

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