2014-10-18 12 views
10

Tôi mới đến redis nên tôi đang làm sai điều gì đó, tôi chắc chắn:StackExchange.Redis server.Keys (mẫu: "IsVerySlow *")

Tôi đã lưu trữ khoảng 16.000 khóa/giá trị trong Azure Redis.

tôi đã sử dụng sau đây để viết các phím/giá trị

 foreach (var worksheet in wksList) 
     { 
     var wksYYMM = string.Format("{0}{1:00}", worksheet.ReviewDt.Year, worksheet.ReviewDt.Month); 
     var wksKey = string.Format("{0}:{1}:{2}", provCode, wksYYMM, worksheet.AcctNbr); 
     string jsonStr = JsonConvert.SerializeObject(MakeWsListDto(worksheet, provCoderList, rvrList)); 
     cache.StringSet(wksKey, jsonStr); 
     } 

để các phím của tôi trông như thế này: "AP: 201.401: AZ5798BK"

Khi tôi cố gắng một tra cứu như:

var keys = server.Keys(pattern: "AP:201401:*"); // returns in milliseconds 
    var keyAry = keys.ToArray(); // returns in over one minute 
    (note: this returns 12 keys) 

phải mất 1 phút 12 giây để trả lại khóa. Khi tôi có các khóa, phải mất một phần nghìn giây để truy xuất các giá trị cho các khóa đó. Nếu tôi lặp lại giá trị của các khóa và trả về các giá trị tôi nhận được một kết quả tương tự. Tôi đã làm một ToArray() chỉ để cô lập vấn đề.

Nếu tôi thử cùng một truy vấn trong redis-cli.exe, nó sẽ trở lại tính bằng mili giây.

Tôi có sử dụng lệnh này không chính xác không?

Trả lời

15

server.Keys tự động lựa chọn giữa KEYS và ưa thích SCAN dựa trên phiên bản máy chủ. Tôi nghi ngờ điều đang xảy ra là bạn đang sử dụng SCAN với kích thước trang quá nhỏ. Có một tham số tùy chọn cho kích thước trang. Thử chỉ định một thứ gì đó lớn hơn đáng kể so với mặc định - hàng trăm, hàng nghìn, v.v. Nếu không được chỉ định, kích thước trang sẽ sử dụng sốcủa Redis 10, điều này có thể gây ra nhiều chuyến đi khứ hồi.

+0

Cảm ơn Marc Tôi sẽ cố gắng và cho bạn biết nó như thế nào. Điều đó có thể giải thích tại sao redis-cli.exe lại nhanh hơn rất nhiều. – Weej

+1

Marc! Vâng đó là câu trả lời. Một câu hỏi tiếp theo: Tôi đã làm một thử nghiệm tối ưu hóa nhỏ và thấy rằng tôi tiếp tục nhận được hiệu suất tăng với kích thước trang đến năm 2000 mặc dù nó đã giảm xuống khoảng năm 1650. Vào thời điểm đó, nó đã giảm đi ở khoảng 180 mili giây. Hai câu hỏi: Tối ưu hóa trang có phải là một chức năng của kích thước db hoặc khóa không? Câu hỏi thứ hai: phân bổ bộ nhớ cho các trang có xảy ra trên máy khách hay máy chủ không? Cảm ơn rất nhiều vì câu trả lời của bạn! – Weej

+0

Điều này đã giúp tôi giải quyết vấn đề hiệu suất tương tự với 'server.Keys'. Cảm ơn! – G0dsquad

6

Không sử dụng KEYS - đó là lệnh chặn sẽ hiển thị máy chủ Redis của bạn không khả dụng với yêu cầu khác trong khi đang chạy. Trích dẫn từ command's documentation:

Cảnh báo: xem xét KEYS như một lệnh mà chỉ nên được sử dụng trong các môi trường sản xuất với cẩn thận. Nó có thể làm hỏng hiệu suất khi nó được thực thi dựa trên cơ sở dữ liệu lớn. Lệnh này nhằm mục đích để gỡ lỗi và các hoạt động đặc biệt, chẳng hạn như thay đổi không gian phím bố cục của bạn. Không sử dụng KEYS trong mã ứng dụng thông thường của bạn. Nếu bạn đang tìm cách tìm khóa trong tập con của không gian phím, hãy xem xét bằng QUÉT hoặc bộ.

Nếu bạn đọc kỹ cảnh báo, bạn sẽ nhận thấy các phương pháp được đề xuất ở cuối đoạn, cụ thể là sử dụng tập hợp SCAN hoặc Redis. QUÉT không bị chặn nhưng vì câu hỏi của bạn cho thấy rằng bạn đang sử dụng hiệu suất, tôi khuyên bạn nên sử dụng bộ.

Ý tưởng là duy trì Redis được đặt với tất cả tên khóa được liên kết với "mẫu" đó, vì vậy trong ví dụ của bạn, bạn phải thực hiện StackExchange.Redis tương đương với SADD AP:201401 AP:201401:AZ5798BK sau khi gọi tới cache.SetString, ví dụ:

cache.SetAdd(wksYYMM, wksKey); 

Disclaimer: tôi không phải là một lập trình viên C# tôi cũng không quá quen thuộc với StackExchange.Redis (xin lỗi Marc;))

Bây giờ, thay vì KEYS hoặc quét để lấy key của bạn, chỉ cần làm SMEMBERS AP:201401 hoặc có thể:

var keys = cache.Members(wksYYMM); 

Bonus: kể từ khi bạn đang thực sự quan tâm đến các giá trị của các phím này, bạn có thể sử dụng Redis' Lua kịch bản để lấy các giá trị khóa dựa trên các thành viên của bộ, hoặc chỉ sử dụng SORT.

Redis tinh khiết:

SORT AP:201401 BY nosort GET *` 

C# & StackExchange.Redis:

vals = cache.Sort(wksYYMM, by = "nosort", get = "*"); 
+2

server.Keys thực sự sử dụng SCAN tự động nếu có. Thông tin thêm về câu trả lời riêng. –

+0

Ahh, rất thông minh :) –

+0

Tôi khá hài lòng với việc triển khai, tôi phải thừa nhận. Trình tự liệt kê nó tự động đưa bạn trở lại cuộn/trang khi bạn làm việc thông qua dữ liệu. –

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