2012-02-03 24 views
18

Mô hình của tôi có các thực thể khác nhau mà tôi muốn tính toán một lần giống như nhân viên của công ty. Để tránh làm cho cùng một truy vấn một lần nữa và một lần nữa, danh sách tính toán được lưu trong Memcache (duration = 1day) .. Vấn đề là các ứng dụng đôi khi cho tôi một lỗi rằng có nhiều byte được lưu trữ trong Memcache hơn là cho phép:Tránh giới hạn Memcache "1000000 bytes" chiều dài trên các giá trị

Values may not be more than 1000000 bytes in length; received 1071339 bytes 

Lưu trữ danh sách đối tượng mà bạn nên làm với Memcache? Nếu vậy, thực tiễn tốt nhất để tránh lỗi ở trên là gì? Tôi hiện đang kéo 1000 đồ vật. Bạn có giới hạn giá trị cho < 200 không? Việc kiểm tra kích thước của một đối tượng trong bộ nhớ có vẻ không quá ý tưởng bởi vì chúng có thể được xử lý (được tuần tự hóa hoặc giống như vậy) trước khi đi vào Memcache.

+0

Lần đầu tiên tôi đọc tiêu đề của câu hỏi tôi nghĩ rằng Memcache ở đây chỉ có thể lưu trữ 1 triệu như trong 1 triệu giá trị.Tiêu đề có thể thay đổi thành "Tránh giới hạn giá trị Memcache 1MB" không? –

Trả lời

28

David, bạn không nói ngôn ngữ bạn sử dụng, nhưng trong Python bạn có thể làm điều tương tự như Ibrahim gợi ý sử dụng dưa chua. Tất cả những gì bạn cần làm là viết hai hàm trợ giúp nhỏ để đọc và viết một đối tượng lớn vào memcache. Dưới đây là một (chưa được kiểm tra) phác thảo:

def store(key, value, chunksize=950000): 
    serialized = pickle.dumps(value, 2) 
    values = {} 
    for i in xrange(0, len(serialized), chunksize): 
    values['%s.%s' % (key, i//chunksize)] = serialized[i : i+chunksize] 
    return memcache.set_multi(values) 

def retrieve(key): 
    result = memcache.get_multi(['%s.%s' % (key, i) for i in xrange(32)]) 
    serialized = ''.join([v for k, v in sorted(result.items()) if v is not None]) 
    return pickle.loads(serialized) 
+1

Cảm ơn Guido cho bản phác thảo, nó mang lại cho tôi cơ sở phù hợp để tiến lên phía trước. –

+0

Tôi có một vấn đề tương tự như @Nikolay, dòng pickle.loads đã thất bại vì các giá trị đã trở lại theo thứ tự khác so với chúng đã được ngâm. Tôi đã sử dụng serialized_data = [result [key] cho khóa trong các khóa nếu khóa trong kết quả và kết quả [key] không phải là None] để giải quyết vấn đề của tôi. – John

+0

Tôi gặp sự cố khi hiểu mã này hoàn toàn. Tôi có thể yêu cầu ai đó giải thích những gì nó từng bước? – puoyaahhh

8

Tôi thường lưu trữ các đối tượng có kích thước vài megabyte trên memcache. Tôi không thể bình luận về việc đây có phải là một thực hành tốt hay không, nhưng ý kiến ​​của tôi là đôi khi chúng ta chỉ cần một cách tương đối nhanh để chuyển các megabyte dữ liệu giữa các phiên bản công cụ ứng dụng của chúng ta.

Vì tôi đang sử dụng Java, những gì tôi đã làm là tuần tự hóa các đối tượng thô của mình bằng trình nối tiếp của Java, tạo ra một chuỗi các byte được tuần tự hóa. Vì kích thước của đối tượng được tuần tự hóa đã được biết, tôi có thể cắt thành các mảng byte 800 KBs. Sau đó tôi gói gọn mảng byte trong một đối tượng chứa và lưu trữ đối tượng đó thay vì các đối tượng thô.

Mỗi đối tượng vùng chứa có thể trỏ đến khóa memcache tiếp theo, nơi tôi có thể tìm nạp mảng mảng byte tiếp theo hoặc null nếu không có nhiều đoạn cần tìm nạp từ memcache. (tức là giống như một danh sách liên kết) tôi sau đó tái hợp nhất các mảng của mảng byte thành một mảng byte lớn và deserialize nó bằng cách sử dụng deserializer của Java.

+0

Cảm ơn Ibrahim, nó chắc chắn là một giải pháp sáng tạo. Tôi đang tìm cách xem những cách tiếp cận tiêu chuẩn đơn giản hơn có để lưu trữ các danh sách đối tượng trong memcache. –

5

Bạn có luôn luôn cần truy cập tất cả dữ liệu mà bạn lưu trữ không? Nếu không thì bạn sẽ được hưởng lợi từ việc phân vùng tập dữ liệu và chỉ truy cập vào phần dữ liệu bạn cần.

Nếu bạn hiển thị danh sách 1000 nhân viên, bạn có thể sẽ phân trang nó. Nếu bạn phân trang thì bạn chắc chắn có thể phân vùng.

Bạn có thể tạo hai danh sách tập dữ liệu của mình: một bật lửa chỉ với thông tin quan trọng nhất có thể phù hợp với 1 MB và danh sách khác được chia thành nhiều phần với thông tin đầy đủ. Trên danh sách ánh sáng, bạn sẽ có thể áp dụng các hoạt động thiết yếu nhất cho ví dụ lọc thông qua tên nhân viên hoặc phân trang. Và sau đó khi cần tải tập dữ liệu nặng, bạn sẽ chỉ có thể tải các phần mà bạn thực sự cần.

Nhưng những đề xuất này cần có thời gian để triển khai. Nếu bạn có thể sống với thiết kế hiện tại của bạn sau đó chỉ cần chia danh sách của bạn thành các khối ~ 300 mục hoặc bất kỳ số nào là an toàn và tải tất cả và hợp nhất.

+1

Phát hiện ý tưởng Skirmantas! Bạn nói đúng, họ sẽ thực hiện thời gian thực hiện nhưng chúng đáng xem xét. Cảm ơn bạn đã chia sẻ lời khuyên của mình. –

3

Nếu bạn biết làm thế nào lớn các đối tượng sẽ là bạn có thể sử dụng tùy chọn memcached để cho phép đối tượng lớn hơn:

memcached -I 10m 

này sẽ cho phép đối tượng lên đến 10MB.

+2

Cảm ơn. Hữu ích khi biết, nhưng có vẻ như đây không phải là tùy chọn trên AppEngine được gắn thẻ làm nền tảng của câu hỏi gốc: https://cloud.google.com/appengine/docs/python/memcache/#Python_Limits – Michael

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