Điều này dự kiến sẽ được lưu trữ dữ liệu hiệu quả: các từ phải được lập chỉ mục trong bộ nhớ trong cấu trúc dữ liệu động của các ô được liên kết bởi con trỏ. Kích thước của cấu trúc siêu dữ liệu, con trỏ và phân bổ bộ nhớ phân bổ nội bộ là lý do tại sao dữ liệu mất nhiều bộ nhớ hơn một tệp phẳng tương ứng.
Tập hợp Redis được triển khai dưới dạng bảng băm. Điều này bao gồm:
- một mảng của con trỏ phát triển về mặt hình học (quyền hạn của hai)
- một mảng thứ hai có thể được yêu cầu khi gia tăng chước hay rập khuôn được kích hoạt
- đơn liên kết các tế bào danh sách đại diện cho các mục trong bảng băm (3 con trỏ, 24 byte cho mỗi entry)
- wrappers đối tượng Redis (một cho mỗi giá trị) (16 byte cho mỗi entry)
- dữ liệu thực tế bản thân (mỗi trong số họ bắt đầu bằng 8 byte cho kích thước và công suất)
Tất cả các kích thước trên được đưa ra để thực hiện 64 bit. Kế toán chi phí cấp phát bộ nhớ, kết quả là Redis lấy ít nhất 64 byte cho mỗi mục thiết lập (trên đầu trang của dữ liệu) cho phiên bản Redis gần đây bằng cách sử dụng trình phân bổ jemalloc (> = 2.4)
Redis cung cấp memory optimizations cho một số các kiểu dữ liệu, nhưng chúng không bao gồm các bộ chuỗi. Nếu bạn thực sự cần tối ưu hóa bộ nhớ tiêu thụ của bộ, có những thủ thuật bạn có thể sử dụng mặc dù. Tôi sẽ không làm điều này cho chỉ 160 MB RAM, nhưng bạn nên có dữ liệu lớn hơn, đây là những gì bạn có thể làm.
Nếu bạn không cần liên minh, giao lộ, khả năng khác biệt của bộ, thì bạn có thể lưu trữ các từ của mình trong đối tượng băm. Lợi ích là các đối tượng băm có thể được tối ưu hóa tự động bởi Redis bằng cách sử dụng zipmap nếu chúng đủ nhỏ. Cơ chế zipmap đã được thay thế bằng ziplist trong Redis> = 2.6, nhưng ý tưởng là như nhau: sử dụng cấu trúc dữ liệu tuần tự có thể vừa với bộ nhớ cache của CPU để có được cả hiệu suất và dấu chân bộ nhớ nhỏ gọn.
Để đảm bảo các đối tượng băm đủ nhỏ, dữ liệu có thể được phân phối theo một số cơ chế băm.Giả sử bạn cần lưu trữ các mặt hàng 1M, thêm một từ có thể được thực hiện theo cách sau:
- băm nó modulo 10000 (thực hiện về phía khách hàng)
- lời HMSET: [hashnum] [từ] 1
Thay vì lưu trữ:
words => set{ hi, hello, greetings, howdy, bonjour, salut, ... }
bạn có thể lưu trữ:
words:H1 => map{ hi:1, greetings:1, bonjour:1, ... }
words:H2 => map{ hello:1, howdy:1, salut:1, ... }
...
Để truy xuất hoặc kiểm tra sự tồn tại của một từ, nó giống nhau (băm và sử dụng HGET hoặc HEXISTS).
Với chiến lược này, tiết kiệm bộ nhớ đáng kể có thể được thực hiện cung cấp các modulo của băm được chọn theo cấu hình zipmap (hoặc ziplist cho Redis> = 2.6):
# Hashes are encoded in a special way (much more memory efficient) when they
# have at max a given number of elements, and the biggest element does not
# exceed a given threshold. You can configure this limits with the following
# configuration directives.
hash-max-zipmap-entries 512
hash-max-zipmap-value 64
Hãy coi chừng: tên của các tham số này đã thay đổi với Redis> = 2.6.
Ở đây, modulo 10000 cho 1M mục có nghĩa là 100 mục cho mỗi đối tượng băm, sẽ đảm bảo rằng tất cả các mục được lưu trữ dưới dạng zipmaps/ziplists.
Câu trả lời thú vị và chi tiết; Tôi không biết điều đó. Cảm ơn @Didier! –
Được rồi, tôi cảm ơn rất nhiều vì điều này sẽ giải quyết được vấn đề của tôi. Và yeah cho 160mb tốt của nó nhưng tôi đang mong đợi để làm việc với lên đến 1gb dữ liệu từ đồng bằng và không muốn rằng để tăng đột biến đến 10gb. Cảm ơn rất nhiều lần nữa, đánh giá cao câu trả lời chi tiết. – cwoebker
@Didier - Câu trả lời hay! Một vài sửa chữa mặc dù a) Các mục Hashtable là một danh sách liên kết duy nhất, không phải gấp đôi, chi phí trên 24 byte là chính xác mặc dù b) Trình bao bọc đối tượng Redis không áp dụng cho mỗi mục nhập bộ/băm. Nó chỉ áp dụng cho cặp khóa/giá trị cấp cao nhất - vì vậy chi phí là hằng số c) Bạn có thể muốn chỉ ra rằng bản đồ zip không được chấp nhận trong 2.6/không ổn định và ziplist đó thực hiện điều tương đương. –