2008-11-04 42 views
8

Phiên bản ngắnTìm kiếm trên phân đoạn?

Nếu tôi chia người dùng thành phân đoạn, làm cách nào để cung cấp "tìm kiếm người dùng"? Rõ ràng, tôi không muốn mọi tìm kiếm đánh trúng mọi mảnh vỡ.

Long phiên bản

By mảnh vỡ, tôi có nghĩa là có nhiều cơ sở dữ liệu trong đó mỗi chứa một phần nhỏ trong tổng số dữ liệu. Ví dụ, một cơ sở dữ liệu UserA, UserB, vv có thể chứa những người dùng có tên bắt đầu bằng "A", "B", v.v. Khi người dùng mới đăng ký, tôi đơn giản kiểm tra tên của anh ta và đưa anh ta vào đúng cơ sở dữ liệu. Khi người dùng quay trở lại đăng nhập, tôi lại nhìn vào tên của anh ấy để xác định cơ sở dữ liệu chính xác để lấy thông tin của anh ấy.

Lợi thế của sharding vs đọc nhân rộng là sao chép đọc không quy mô viết của bạn. Tất cả các bài viết mà đi tới thầy đều phải đi tới từng nô lệ. Trong một nghĩa nào đó, tất cả chúng đều mang cùng tải ghi, mặc dù tải đọc được phân phối.

Trong khi đó, phân đoạn không quan tâm đến việc viết của nhau. Nếu Brian đăng ký trên phân đoạn UserB, phân đoạn UserA không cần phải nghe về nó. Nếu Brian gửi một tin nhắn cho Alex, tôi có thể ghi lại sự thật đó trên cả hai phân đoạn UserA và UserB. Bằng cách này, khi một trong hai Alex hoặc Brian đăng nhập, anh ta có thể truy xuất tất cả các tin nhắn đã gửi và nhận của mình từ phân đoạn của chính mình mà không truy vấn tất cả các mảnh vỡ.

Cho đến nay, rất tốt. Điều gì về tìm kiếm? Trong ví dụ này, nếu Brian tìm kiếm "Alex", tôi có thể kiểm tra UserA. Nhưng nếu anh ta tìm Alex bằng họ của mình, "Smith" thì sao? Có Smiths trong mọi phân đoạn. Từ đây, tôi thấy hai tùy chọn:

  1. Yêu cầu ứng dụng tìm kiếm Smith trên mỗi phân đoạn. Điều này có thể được thực hiện chậm (truy vấn từng phân đoạn liên tiếp) hoặc nhanh chóng (truy vấn từng phân đoạn song song), nhưng theo một trong hai cách, mọi phân đoạn cần phải được tham gia vào mọi tìm kiếm. Trong cùng một cách mà đọc sao chép không quy mô viết, có tìm kiếm nhấn mỗi phân đoạn không quy mô tìm kiếm của bạn. Bạn có thể đạt được thời gian khi khối lượng tìm kiếm của bạn đủ cao để áp đảo từng phân đoạn và việc thêm phân đoạn không giúp bạn, vì tất cả chúng đều có cùng khối lượng.
  2. Một số loại lập chỉ mục mà chính nó có khả năng chịu được sharding. Ví dụ, giả sử tôi có một số trường liên tục mà tôi muốn tìm kiếm: họ và tên. Ngoài UserA, UserB, vv Tôi cũng có IndexA, IndexB, vv Khi một người dùng mới đăng ký, tôi đính kèm anh ta vào từng chỉ mục mà tôi muốn anh ta được tìm thấy trên đó. Vì vậy, tôi đặt Alex Smith vào cả IndexA và IndexS, và anh ta có thể được tìm thấy trên một trong hai "Alex" hoặc "Smith", nhưng không có chất nền. Bằng cách này, bạn không cần truy vấn từng phân đoạn, vì vậy tìm kiếm có thể mở rộng được.

Vì vậy, có thể tìm kiếm được chia tỷ lệ? Nếu vậy, cách tiếp cận này có lập chỉ mục đúng không? Có cái nào khác không?

Trả lời

2

tôi giả sử bạn đang nói về mảnh a la: http://highscalability.com/unorthodox-approach-database-design-coming-shard

Nếu bạn đọc mà bài anh đi vào một số chi tiết về chính xác câu hỏi của bạn, nhưng câu trả lời dài ngắn, bạn viết mã ứng dụng tùy chỉnh để mang lại các mảnh vỡ khác nhau với nhau. Bạn có thể làm một số băm thông minh để truy vấn cả hai mảnh riêng lẻ và chèn dữ liệu vào phân đoạn. Bạn cần đặt câu hỏi cụ thể hơn để có câu trả lời cụ thể hơn.

+0

Cảm ơn. Tôi đã thực sự đọc trang web đó một cách rộng rãi. Tôi đã cố làm sáng tỏ câu hỏi của mình ở trên; mà hy vọng là vượt ra ngoài bài viết bạn đã liên kết một cách hữu ích. –

1

Bạn thực sự cần mọi tìm kiếm để đạt được mọi phân đoạn hoặc ít nhất mọi tìm kiếm cần được thực hiện dựa vào chỉ mục chứa dữ liệu từ tất cả các phân đoạn.

Có lẽ bạn phân đoạn dựa trên một thuộc tính duy nhất của người dùng, có thể là băm của tên người dùng. Nếu tính năng tìm kiếm của bạn cho phép người dùng tìm kiếm dựa trên các thuộc tính khác của người dùng thì rõ ràng là không có phân mảnh hoặc tập hợp con nào có thể đáp ứng truy vấn, bởi vì bất kỳ phân đoạn nào cũng có thể chứa người dùng phù hợp với truy vấn. Bạn không thể loại trừ bất kỳ phân đoạn nào trước khi thực hiện tìm kiếm, điều này ngụ ý rằng bạn phải chạy truy vấn đối với tất cả các phân đoạn.

+0

Vui lòng xem làm rõ của tôi ở trên. –

7

Không có dấu đầu dòng ma thuật.

Tìm kiếm từng phân đoạn liên tiếp không nằm trong câu hỏi, rõ ràng là do độ trễ cực kỳ cao mà bạn sẽ phải chịu.

Vì vậy, bạn muốn tìm kiếm song song, nếu bạn có.

Có hai tùy chọn thực tế và bạn đã liệt kê chúng - lập chỉ mục và tìm kiếm song song. Cho phép tôi đi sâu hơn một chút về cách bạn sẽ thiết kế chúng.

Thông tin chi tiết quan trọng bạn có thể sử dụng là trong tìm kiếm, bạn hiếm khi cần tập hợp kết quả hoàn chỉnh. Bạn chỉ cần trang kết quả đầu tiên (hoặc thứ n). Vì vậy, có khá nhiều phòng lung linh bạn có thể sử dụng để giảm thời gian phản hồi.

Indexing

Nếu bạn biết các thuộc tính mà trên đó người dùng sẽ được tìm kiếm, bạn có thể tạo tùy chỉnh, chỉ số riêng biệt cho họ. Bạn có thể xây dựng inverted index của riêng mình, nó sẽ trỏ đến (shard, recordId) tuple cho mỗi cụm từ tìm kiếm hoặc bạn có thể lưu trữ nó trong cơ sở dữ liệu. Cập nhật nó một cách uể oải và không đồng bộ. Tôi không biết yêu cầu ứng dụng của bạn, thậm chí có thể chỉ xây dựng lại chỉ mục mỗi đêm (có nghĩa là bạn sẽ không có các mục nhập gần đây nhất vào bất kỳ ngày nào - nhưng điều đó có thể phù hợp với bạn). Đảm bảo tối ưu hóa chỉ mục này cho kích thước để nó có thể vừa với bộ nhớ; lưu ý rằng bạn có thể phân tích chỉ mục này, nếu bạn cần.

Đương nhiên, nếu mọi người có thể tìm kiếm thứ gì đó như "lastname='Smith' OR lastname='Jones'", bạn có thể đọc chỉ mục cho Smith, đọc chỉ mục cho Jones và tính toán liên kết - bạn không cần lưu trữ tất cả các truy vấn có thể.

Parallel Tìm kiếm

Đối với mỗi truy vấn, gửi đi các yêu cầu cho mọi mảnh vỡ trừ khi bạn biết rằng những mảnh vỡ để tìm kiếm vì việc tìm kiếm sẽ xảy ra là trên phím phân phối. Thực hiện các yêu cầu không đồng bộ. Trả lời người dùng ngay khi bạn nhận được kết quả trang đầu tiên; thu thập phần còn lại và bộ nhớ cache cục bộ, để nếu người dùng nhấn "tiếp theo", bạn sẽ có kết quả sẵn sàng và không cần phải truy vấn lại máy chủ. Bằng cách này, nếu một số máy chủ đang mất nhiều thời gian hơn các máy chủ khác, bạn không cần phải chờ chúng phục vụ yêu cầu.

Khi bạn đang ở đó, hãy ghi lại thời gian phản hồi của máy chủ được phân loại để quan sát các vấn đề tiềm ẩn với dữ liệu không đồng đều và/hoặc phân phối tải.

1

Bạn có thể muốn xem Sphinx (http://www.sphinxsearch.com/articles.html). Nó hỗ trợ tìm kiếm phân tán. GigaSpaces có truy vấn song song và hỗ trợ hợp nhất. Điều này cũng có thể được thực hiện với MySQL Proxy (http://jan.kneschke.de/2008/6/2/mysql-proxy-merging-resultsets).

Để xây dựng các loại thất bại không được đánh chỉ mục, mục đích của phân đoạn ở nơi đầu tiên :-) Chỉ mục tập trung có thể sẽ không hoạt động nếu phân đoạn là cần thiết.

Tôi nghĩ rằng tất cả các mảnh cần phải được nhấn song song.Các kết quả cần được lọc, xếp hạng, sắp xếp, nhóm và kết quả được sáp nhập từ tất cả các phân đoạn. Nếu bản thân các mảnh vỡ trở nên quá tải, bạn phải làm như bình thường (reshard, scale up, vv) để làm chúng trở nên chán nản.

0

RDBM không phải là công cụ tốt cho tìm kiếm văn bản. Bạn sẽ tốt hơn khi nhìn vào Solr. Hiệu suất khác biệt giữa Solr và cơ sở dữ liệu sẽ theo thứ tự độ lớn 100X.

Các vấn đề liên quan