Redis lấy Nodejs

Redis là một máy chủ cơ sở dữ liệu mã nguồn mở đã trở nên phổ biến gần đây. Đó là kho lưu trữ khóa-giá trị trong bộ nhớ. Nó giữ tất cả dữ liệu trong bộ nhớ để truy cập nhanh, nhưng cũng giữ dữ liệu trong đĩa nếu bạn bảo nó. Đó là kho lưu trữ khóa-giá trị cơ bản trong đó khóa và giá trị là các chuỗi, nhưng nó cũng chứa nhiều cấu trúc thú vị hơn như số nguyên, danh sách, bộ, bộ được sắp xếp và từ điển, đồng thời cũng chứa một số tính năng nâng cao như pub-sub, chặn pop, giám sát khóa

Redis là con dao Thụy Sĩ của cơ sở dữ liệu trong bộ nhớ. bạn có thể sử dụng nó để triển khai nhiều trường hợp sử dụng khác nhau, từ bộ đệm dữ liệu hoặc hàng đợi công việc đến nhật ký thống kê

Redis nguyên thủy

Trong Node, để truy cập Redis, bạn sẽ cần cài đặt thư viện máy khách. Cái được sử dụng và thử nghiệm nhiều nhất là

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
8

$ npm install redis --save

“Nếu bạn chưa thực hiện, để tự cài đặt Redis, bạn nên làm theo hướng dẫn trên trang web chính thức tại http. //redis. io/tải xuống. ”

làm lại. js

var redis = require('redis');module.exports = redis.createClient();

Mô-đun

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
8 cục bộ này sử dụng mô-đun NPM
redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
8 chính thức đã cài đặt để tạo một đối tượng máy khách, đây là đối tượng mà mô-đun này xuất ra

Theo tùy chọn, bạn có thể chuyển vào một số tùy chọn máy khách nếu bạn đang lưu trữ Redis ở một cổng khác hoặc trong một máy chủ mạng khác

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);

Để sử dụng mô-đun này từ bất kỳ tệp nào khác, bạn chỉ cần yêu cầu nó như thế này

client_example. js

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});

Ở đây trong ví dụ cuối cùng này, chúng tôi đang đặt một khóa và sau đó nhận giá trị cho khóa đó, khẳng định rằng đó thực sự là những gì chúng tôi đã chèn

Bây giờ, hãy xem xét một số nguyên hàm hữu ích của Redis và cách sử dụng chúng trong Node

Dây

Trong Redis, tất cả các khóa đều là chuỗi và giá trị thường là chuỗi. (Chúng ta sẽ thấy một số ví dụ sử dụng số và đối tượng sau. ) Như chúng ta đã thấy, để đặt khóa cho chuỗi bạn sử dụng

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
1, cung cấp khóa và chuỗi giá trị

________số 8

Đối với mọi lệnh Redis, bạn có thể chuyển vào một lệnh gọi lại để được gọi khi lệnh hoàn thành hoặc có lỗi

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});

Bạn cũng có thể lấy giá trị chuỗi của bất kỳ khóa nào bằng lệnh

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
2

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
Khóa hết hạn

Bên cạnh các hoạt động khóa-giá trị cơ bản, Redis có vô số chức năng hữu ích. Một trong số đó là hết hạn khóa. Bạn có thể xác định thời gian hết hạn mà sau đó mục nhập sẽ bị xóa khỏi Redis. Hãy xem điều này trong hành động

hết hạn. js

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);

Ở đây, chúng tôi đang đặt một khóa và sau đó hết hạn sau hai giây trôi qua. Sau đó, chúng tôi thăm dò Redis về giá trị trên khóa đó cho đến khi Redis xóa bản ghi đó, tại thời điểm đó chúng tôi chấm dứt tập lệnh hiện tại

“Bạn có thể nhận thấy rằng trong ví dụ trước, đôi khi chúng tôi gọi Redis mà không cung cấp lệnh gọi lại. Điều này có an toàn không? . khi phát hành một số lệnh trên cùng một máy khách, máy khách chỉ thực hiện một lệnh tại một thời điểm; . Điều này xảy ra vì giao thức Redis chỉ cho phép một lệnh đang chạy trên mỗi kết nối. Nếu xảy ra lỗi và bạn không cung cấp lệnh gọi lại, lỗi sẽ được phát ra trên máy khách. Khi điều này xảy ra, bạn sẽ mất tất cả ngữ cảnh của lỗi. Đây là lý do tại sao bạn phải luôn cung cấp lệnh gọi lại trong các lệnh. ”

Bạn có thể kiểm tra điều này bằng cách làm

$ npm install redis --save
3

Nếu bạn cần đặt thời gian hết hạn khi đặt khóa, bạn có thể sử dụng lệnh

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
3 để thay thế

hết hạn_setex. js

$ npm install redis --save
5Giao dịch

Trong ví dụ trước, chúng ta đã thấy một lệnh kết hợp hai lệnh thành một (

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
4 và
var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
5). Bạn cũng có thể chọn kết hợp bất kỳ lệnh nào bạn muốn vào một giao dịch nguyên tử bằng cách sử dụng lệnh
var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
6. Chẳng hạn, nếu bạn muốn đặt nguyên tử hai khóa và đặt ngày hết hạn của một khóa khác, bạn có thể soạn nó như thế này

đa. js

var redis = require('redis');module.exports = redis.createClient();
0

Ở đây, chúng tôi đang xây dựng một lệnh MULTI bằng cách sử dụng

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
7. Sau đó, chúng tôi sẽ thêm các lệnh vào giao dịch này bằng API Redis, nhưng trên nhiều lệnh đã tạo. Sau đó, chúng tôi thực hiện giao dịch bằng cách gọi
var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
8, cung cấp cho nó một cuộc gọi lại

Nếu bạn gặp lỗi, nghĩa là không có lệnh nào hiệu quả. Nếu bạn không gặp lỗi, điều này có nghĩa là mỗi lệnh đã thành công

“Tất cả các lệnh này được ghi lại trên trang web chính thức của Redis. http. //redis. io/lệnh. Với một vài ngoại lệ, ứng dụng khách

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
9 tuân theo thứ tự đối số chính xác và nhập như được ghi lại. ”

Kết quả lệnh trong Multi

Bên cạnh việc thực hiện nhiều lệnh, bạn cũng có thể thực hiện nhiều truy vấn hoặc kết hợp các lệnh và truy vấn, nhận kết quả ở cuối. Hãy xem điều này trong hành động

multi_read. js

var redis = require('redis');module.exports = redis.createClient();
1

Nếu bạn thực hiện điều này, bạn sẽ nhận được đầu ra sau

var redis = require('redis');module.exports = redis.createClient();
2

Ở đây bạn có thể thấy rằng kết quả được chuyển đến cuộc gọi lại của chúng tôi là một mảng chứa vị trí cho kết quả của từng thao tác trong giao dịch của chúng tôi. Thao tác

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
4 (vị trí 0 và 2) dẫn đến chuỗi
$ npm install redis --save
31 (đây là cách Redis biểu thị thành công);

Khóa lạc quan bằng WATCH

Lệnh

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
6 có thể mạnh, nhưng bạn vẫn không thể đưa ra các thao tác so sánh và thiết lập nguyên tử. Ví dụ: giả sử bạn muốn thực hiện một thao tác trong đó bạn đọc một giá trị số nguyên từ khóa
$ npm install redis --save
34, sau đó bạn thêm 1 vào giá trị đó và lưu trữ lại

var redis = require('redis');module.exports = redis.createClient();
3

Cách tiếp cận này có một vấn đề rõ ràng mặc dù. nó không cho phép khách hàng đồng thời an toàn. Nếu có nhiều máy khách đang thực hiện thao tác này song song, thì nhiều máy khách có thể đọc cùng một giá trị, tăng giá trị đó và sau đó lưu cùng một kết quả. Điều này có nghĩa là, thay vì tăng giá trị một cách nguyên tử, chúng ta sẽ mất các giá trị gia tăng. Điều này có thể được giải quyết bằng cách sử dụng kết hợp

$ npm install redis --save
35 và
var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
6

var redis = require('redis');module.exports = redis.createClient();
4

Ở đây chúng ta đang định nghĩa một hàm

$ npm install redis --save
37 chung nhận một khóa và một hàm gọi lại. Sau khi xác định chức năng này, chúng tôi sử dụng nó để tăng khóa
$ npm install redis --save
34. Khi điều này được thực hiện, chúng tôi chấm dứt kết nối máy khách Redis

Hàm

$ npm install redis --save
37 bắt đầu bằng cách xem phím, sau đó bắt đầu lệnh
var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
6. Sau đó, chúng tôi tính toán giá trị mới cho A và nối lệnh
var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
4 vào đa. Sau đó, chúng tôi thực thi đa lệnh một lệnh này, chuyển hàm
$ npm install redis --save
52 của chúng tôi dưới dạng gọi lại. Chức năng này phát hiện xung đột. Lệnh
var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
6 trả về giá trị
$ npm install redis --save
54 (thay vì
$ npm install redis --save
31 truyền thống) khi phát hiện xung đột. Xung đột xảy ra khi bất kỳ khóa nào đã xem (trong trường hợp của chúng tôi, chỉ một khóa) được ghi bởi một kết nối khác. Trong trường hợp này, chúng tôi phát hiện xung đột và đưa ra lỗi thích hợp với thông báo cho biết đã phát hiện xung đột

Tuy nhiên, có một số khía cạnh phút và có lẽ không rõ ràng đối với kịch bản này. Đầu tiên, chúng tôi đang sử dụng một kết nối cho mỗi giao dịch. Điều này là do Redis giữ một danh sách theo dõi trên mỗi kết nối và thực thi

var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
6 chỉ bị hủy bỏ nếu thao tác ghi trên khóa đã xem được thực hiện trên một kết nối máy khách khác. Ngoài ra, sau khi multi đã được thực thi, danh sách theo dõi sẽ bị loại bỏ. Về cơ bản, sẽ không an toàn khi chia sẻ kết nối nếu bạn đang dựa vào hành vi của danh sách theo dõi

“Phát hành thêm một lệnh

$ npm install redis --save
57 sẽ thêm một khóa vào danh sách theo dõi kết nối. Bạn có thể xóa danh sách theo dõi bằng lệnh
$ npm install redis --save
58. ”

Cũng xin lưu ý rằng, vì chúng tôi đang tạo một kết nối Redis cho mỗi lần tăng, nên chúng tôi đặc biệt cẩn thận khi đóng kết nối đó. Điều này có nghĩa là, trong trường hợp có lỗi, chúng tôi luôn gọi hàm

$ npm install redis --save
52, chịu trách nhiệm đóng kết nối với Redis. Chúng tôi phải bao gồm tất cả các tình trạng lỗi – rất dễ rò rỉ các kết nối có thời gian sử dụng ngắn

“Một kết nối cho mỗi giao dịch có nghĩa là cần thêm tài nguyên phía máy khách và phía máy chủ. Hãy cẩn thận với việc đo kích thước hệ thống của bạn khi sử dụng tính năng này, vì nó dễ gây gánh nặng cho các quy trình Node hoặc máy chủ Redis trong thời gian lưu lượng truy cập cao nhất. ”

Chúng tôi có thể kiểm tra khả năng phát hiện xung đột bằng cách phát hành đồng thời nhiều hơn một số gia ở cuối tệp cuối cùng

kết thúc của increment_watch. js

var redis = require('redis');module.exports = redis.createClient();
5

Hãy chạy tập lệnh này

var redis = require('redis');module.exports = redis.createClient();
6

Nhưng bây giờ chúng tôi có thể phát hiện xung đột đúng cách, chúng tôi có thể xử lý chúng và thử thực hiện lại giao dịch

tăng đồng hồ thử lại. js

var redis = require('redis');module.exports = redis.createClient();
7

Ở đây, chúng tôi đã đổi tên hàm

$ npm install redis --save
37 của mình thành
var redis = require('redis');module.exports = redis.createClient();
01 và tạo một hàm
$ npm install redis --save
37 mới xử lý trường hợp đặc biệt khi phát hiện xung đột. Vì chúng tôi được đảm bảo rằng Redis sẽ không cam kết nếu có xung đột, chúng tôi có thể thử gọi lại hàm
var redis = require('redis');module.exports = redis.createClient();
01 một cách an toàn

Bây giờ chúng tôi có thể kiểm tra phiên bản mới này và xác minh rằng tất cả các giao dịch cuối cùng đã thành công, mặc dù chúng được phát đồng thời

var redis = require('redis');module.exports = redis.createClient();
8

Ở đây, chúng tôi đã sử dụng một số gia đơn giản, nhưng bạn có thể dễ dàng thấy rằng chúng tôi có thể sử dụng khóa tối ưu để tạo bất kỳ loại giao dịch tùy chỉnh nào miễn là chúng tôi đang sử dụng các kết nối Redis khác nhau cho mỗi giao dịch và chúng tôi đang xem các khóa cần thiết

Giao dịch sử dụng tập lệnh Lua

Một cách khác để thực hiện các thao tác phức tạp tùy ý theo cách nguyên tử trong Redis là sử dụng các tập lệnh được viết bằng Lua. Redis cung cấp một cách để chúng ta chèn và chạy các tập lệnh Lua bên trong nó. Khi thực thi tập lệnh Lua trong Redis, chúng tôi được đảm bảo rằng không có lệnh hoặc tập lệnh nào khác đang thực thi đồng thời, đó chính xác là điều chúng tôi muốn

Lua là một ngôn ngữ kịch bản đơn giản, hơi giống với JavaScript (mặc dù các mảng bắt đầu ở chỉ mục 1, không phải 0…)

“Nếu bạn không biết Lua, có một số tài nguyên ngoài kia nếu bạn muốn tìm hiểu về nó — nhưng nó rõ ràng nằm ngoài phạm vi của cuốn sách này. Tuy nhiên, chúng tôi sẽ trình bày ở đây một số ví dụ mà bạn có thể thấy hữu ích để làm cơ sở cho các tập lệnh của riêng mình. ”

Trước tiên, chúng tôi sẽ chuyển giao dịch

$ npm install redis --save
37 của mình thành tập lệnh Redis Lua

lua_scripts/tăng. lúa

var redis = require('redis');module.exports = redis.createClient();
9

Ở đây bạn có thể thấy rằng tập lệnh đơn giản này bắt đầu bằng cách lấy tên của khóa từ biến

var redis = require('redis');module.exports = redis.createClient();
05. Đây là một biến ẩn đặc biệt mà Redis chuyển đến tập lệnh, xuất phát từ lệnh gọi của máy khách. Sau đó, chúng tôi nhận được giá trị được lưu trữ trong khóa đó bằng cách gọi công cụ Redis. Các hoạt động Redis có sẵn để được gọi bằng cách sử dụng
var redis = require('redis');module.exports = redis.createClient();
06;

Sau khi nhận được giá trị hiện tại, chúng tôi tăng giá trị đó, lưu trữ và sau đó trả lại giá trị đó dưới dạng kết quả của hoạt động

Đây là phần Nút triển khai chức năng

$ npm install redis --save
37 và ủy quyền cho tập lệnh Lua

gia_lua. js

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
0

Điều đầu tiên chúng tôi làm là tải tập lệnh Lua vào bộ nhớ. Chúng tôi làm điều này bằng cách sử dụng

var redis = require('redis');module.exports = redis.createClient();
08

“Ở đâu đó bạn có thể đã nghe nói rằng việc sử dụng các chức năng đồng bộ của Node là sai - bạn phải luôn sử dụng phiên bản không đồng bộ của các chức năng để không chặn vòng lặp sự kiện của Node. Bạn có thể sử dụng các chức năng đồng bộ trong thời gian chuẩn bị mô-đun - chúng tồn tại ở đây vì điều đó. Theo nguyên tắc thông thường, bạn chỉ cần tránh gọi các hàm đồng bộ từ bên trong hàm gọi lại hoặc trình xử lý sự kiện. ”

Bây giờ chúng ta đã có tập lệnh Lua trong bộ nhớ, chúng ta có thể triển khai hàm

$ npm install redis --save
37, hàm này sẽ tải tập lệnh vào Redis và gọi nó bằng cách sử dụng lệnh
var redis = require('redis');module.exports = redis.createClient();
10. Đối số đầu tiên của
var redis = require('redis');module.exports = redis.createClient();
11 là chính mã script và sau đó là số lượng khóa chúng ta sẽ chuyển. Trong trường hợp của chúng tôi, chúng tôi sẽ chỉ chuyển một đối số chính. Cuối cùng, có một cuộc gọi lại để chúng tôi biết khi thao tác thất bại hoặc thành công và trong trường hợp cuối cùng, kết quả là gì

“Bên cạnh các khóa, bạn cũng có thể truyền các đối số tùy ý mà tập lệnh Lua có thể truy cập bằng cách sử dụng biến mảng ẩn

var redis = require('redis');module.exports = redis.createClient();
12. ”

Bây giờ chúng ta có thể kiểm tra tập lệnh của mình

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
1

Lưu trữ các tập lệnh Lua

Có một vấn đề với lần triển khai cuối cùng của chúng tôi. chúng tôi luôn chuyển tập lệnh Lua trước khi gọi. Điều này chịu trách nhiệm truyền tập lệnh vào Redis, tải Redis, phân tích cú pháp và chạy tập lệnh. Chúng tôi có thể tối ưu hóa điều này bằng cách sử dụng lệnh Redis

var redis = require('redis');module.exports = redis.createClient();
13, lệnh này cho phép chúng tôi gọi một tập lệnh dựa trên thông báo SHA1 của nó. Hãy sử dụng nó để tránh tải cùng một tập lệnh mọi lúc

lua_scripts/chỉ mục. js

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
2

Mã này là một mô-đun chung quản lý việc thực thi các tập lệnh cho bạn. Biến có tên

var redis = require('redis');module.exports = redis.createClient();
14 là một mảng chứa tất cả tên của các tập lệnh có sẵn. Trong trường hợp đơn giản của chúng tôi, chúng tôi chỉ có một tập lệnh có tên
$ npm install redis --save
37, nhưng chúng tôi có thể có nhiều hơn. Khi mô-đun này tải, nó sẽ tải các phần thân của tập lệnh và tính toán thông báo SHA1 của từng phần

Ngoài ra, mô-đun này xuất một hàm

var redis = require('redis');module.exports = redis.createClient();
16 nhận kết nối Redis, tên tập lệnh và một tập hợp các đối số thực thi tập lệnh tùy ý, được hoàn thiện bằng một lệnh gọi lại. Chức năng này bắt đầu bằng cách thử thực thi tập lệnh bằng cách sử dụng
var redis = require('redis');module.exports = redis.createClient();
17, chuyển vào tập lệnh thông báo SHA1. Nếu Redis không thể tìm thấy tập lệnh, quá trình thực thi sẽ tạo ra một thông báo lỗi cụ thể có chứa chuỗi "NOSCRIPT". Khi chúng tôi gặp lỗi như vậy, Redis cho chúng tôi biết rằng nó chưa chứa tập lệnh. sau đó chúng tôi quay lại sử dụng
var redis = require('redis');module.exports = redis.createClient();
11, chuyển vào nội dung tập lệnh thay vì thông báo tập lệnh

Bây giờ chúng ta có thể chỉ cần sử dụng mô-đun này từ tập lệnh máy khách như thế này

tăng luasha. js

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
3

Khi thực thi tập lệnh này, một lần nữa, bạn sẽ thấy kết quả đầu ra giống như trước đây — nhưng bây giờ bạn biết rằng bạn nên cố gắng hết sức để sử dụng lại tập lệnh đã lưu trong bộ nhớ cache

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
4

Hiệu suất

Vì chúng tôi biết rằng tất cả các lệnh và truy vấn Redis được thực hiện trong bộ nhớ và các tập lệnh Lua cũng được thực thi nhanh chóng, nên nếu chúng tôi cẩn thận với số lượng và loại thao tác chúng tôi thực hiện, chúng tôi cũng có thể đảm bảo rằng mỗi giao dịch được thực hiện đủ nhanh để

Mỗi lệnh Redis có độ phức tạp về thời gian được cung cấp cho chúng tôi trong ký hiệu O(). Chẳng hạn, nếu một thao tác đã cho là O(1), chúng ta biết rằng nó sẽ luôn mất cùng một khoảng thời gian cố định

Chẳng hạn, lệnh Redis

var redis = require('redis');module.exports = redis.createClient();
19, lấy phần tử thứ N của danh sách, có độ phức tạp là O(N), trong đó N là số phần tử mà danh sách có. Nếu bạn đang sử dụng lệnh này, bằng cách nào đó bạn phải đảm bảo rằng số phần tử trong danh sách này không bị chặn

số nguyên

Trước đó chúng ta đã thấy cách thực hiện các thao tác nguyên tử trong Redis và chúng ta đã cho thấy ví dụ về việc tăng giá trị số nguyên của một bản ghi. Ví dụ này chỉ được trình bày với mục đích hiển thị một ví dụ đơn giản, vì thực tế là Redis đã có các lệnh tăng và giảm

gia tăng. js

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
5

Nếu bạn thực thi tệp này, bạn sẽ nhận được loại kết quả giống như trong phiên bản tùy chỉnh trước đó

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
6

Bên cạnh việc tăng thêm một, Redis cũng cho phép tăng theo một giá trị số nguyên cụ thể bằng cách sử dụng lệnh

var redis = require('redis');module.exports = redis.createClient();
20

gia tăng. js

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
7

Trong trường hợp này, chúng tôi đang tăng bản ghi lên giá trị 2 mười lần

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
8

Bên cạnh việc tăng, chúng ta cũng có thể giảm

quyết định. js

var redis = require('redis');var port = process.env.REDIS_PORT || 6379;  
var host = process.env.REDIS_HOST || '127.0.0.1';
module.exports = redis.createClient(port, host);
9

Điều này mang lại kết quả mong đợi sau đây

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
0

Redis cũng có lệnh

var redis = require('redis');module.exports = redis.createClient();
21 cho phép chúng tôi giảm một lượng cụ thể

giải mã. js

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
1

Và chạy tập lệnh cuối cùng này mang lại kết quả như sau

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
2Sử dụng bộ đếm

Những nguyên thủy này đưa ra những cách tuyệt vời để thực hiện các bộ đếm cơ bản để lưu trữ và đọc số liệu thống kê. Chẳng hạn, bạn có thể lưu trữ số liệu thống kê theo người dùng về số lượng yêu cầu API. Nếu bạn muốn tăng mức sử dụng API cho mỗi người dùng, bạn có thể sử dụng Redis để lưu trữ bộ đếm yêu cầu API cho mỗi người dùng, bộ đếm này sẽ tự động được đặt lại sau một khoảng thời gian cố định

Chẳng hạn, đây là cách bạn có thể triển khai một chức năng để tăng bộ đếm mức sử dụng API cho một người dùng cụ thể

apithrottling/incrapiusagecounter. js

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
3

Ở đây, chúng tôi đang sử dụng lệnh gọi đa Redis để thực hiện hai thao tác. một để tăng bản ghi và một để lấy TTL (thời gian tồn tại) của bản ghi. Nếu bản ghi TTL chưa được thiết lập, chúng tôi sẽ thiết lập nó bằng cách sử dụng

var redis = require('redis');module.exports = redis.createClient();
22. Nếu TTL đã được đặt, chúng tôi chỉ cần kết thúc hoạt động

“Lệnh TTL mang lại giá trị

var redis = require('redis');module.exports = redis.createClient();
23 cho các bản ghi tồn tại và chưa có TTL. Nếu bản ghi không tồn tại, nó sẽ trả về
var redis = require('redis');module.exports = redis.createClient();
24. Chúng tôi chỉ cần kiểm tra giá trị
var redis = require('redis');module.exports = redis.createClient();
23 vì chúng tôi đang truy vấn TTL trong nhiều quyền sau khi bản ghi được cập nhật, đảm bảo rằng bản ghi tồn tại. ”

Bạn chỉ cần gọi chức năng này trước bất kỳ yêu cầu nào do khách hàng xác thực và nó sẽ tăng bộ đếm sử dụng API của người dùng

Bây giờ chúng ta phải tạo một hàm truy vấn bộ đếm này để xác định xem người dùng có thể sử dụng API hay không

apithrottling/canuseruseapi. js

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
4

Mô-đun này nhận giá trị cho bộ đếm yêu cầu API của người dùng. Nếu nó vượt quá mức tối đa nhất định, chúng tôi nói rằng nó hiện được cho phép. Bây giờ, ứng dụng chỉ cần gọi chức năng này trước bất kỳ xử lý yêu cầu API ứng dụng khách được xác thực nào, đại loại như thế này

điều chỉnh_example. js

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
5

Trong quá trình triển khai, chúng tôi sẽ thất bại nếu có lỗi, nhưng thay vào đó, bạn có thể chọn bỏ qua lỗi từ Redis và tiếp tục, cải thiện tính khả dụng của dịch vụ trong trường hợp Redis ngừng hoạt động

điều tiết ví dụ đàn hồi. js

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
6

Bằng cách sử dụng Redis làm nơi lưu trữ bộ đếm sử dụng API, chúng tôi có thể triển khai một cách tập trung và nhanh chóng để kiểm tra xem người dùng có vượt quá hạn ngạch sử dụng API hay không. Bằng cách sử dụng TTL tích hợp của Redis, chúng tôi không cần thêm công việc để hết hạn bản ghi. Redis làm điều đó cho chúng tôi

từ điển

Bên cạnh các giá trị chuỗi đơn giản, Redis cũng cho phép bạn lưu trữ từ điển chuỗi trong đó khóa và giá trị là chuỗi. Tập hợp các lệnh Redis bắt đầu bằng

var redis = require('redis');module.exports = redis.createClient();
26 và bao gồm
var redis = require('redis');module.exports = redis.createClient();
27,
var redis = require('redis');module.exports = redis.createClient();
28 và
var redis = require('redis');module.exports = redis.createClient();
29, trong số những lệnh khác. Các lệnh này có thể ánh xạ tốt từ và vào các đối tượng nông của JavaScript

Chẳng hạn, bạn có thể lưu trữ hồ sơ người dùng bằng một lệnh set duy nhất như thế này

Thông tin người dùng. js

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
7

Bạn có thể sử dụng mô-đun này, chúng tôi đã nghĩ ra từ ứng dụng của bạn

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
8

Tất nhiên, thay vì sử dụng từ điển Redis, bạn chỉ cần mã hóa JSON và giải mã JSON cho đối tượng hồ sơ người dùng. Sử dụng từ điển Redis ở đây có thể hữu ích nếu bạn muốn lấy hoặc đặt các thuộc tính riêng lẻ mà không cần phải lấy và đặt toàn bộ đối tượng

Chẳng hạn, để lấy email người dùng trong ví dụ này, bạn chỉ cần

var redis = require('./redis');  
var assert = require('assert');
redis.set('key', 'value', function(err) {
if (err) {
throw err
}
redis.get('key', function(err, value) {
if (err) {
throw err
}
assert.equal(value, 'value'); console.log('it works!'); redis.quit();
});
});
9

“Với các thuộc tính bền bỉ và khả dụng, tôi không nghĩ rằng Redis phù hợp với công cụ lưu trữ chính cho bất kỳ ứng dụng nào. Thay vào đó, Redis có thể khá hữu ích với vai trò là bộ lưu trữ thứ cấp nhanh hơn và được sử dụng làm lớp bộ nhớ đệm. ”

Máy đếm từ điển Redis

Một cách sử dụng khác cho từ điển Redis là giúp đặt tên cho các khóa bằng cách lưu trữ một số bộ đếm dưới cùng một khóa. Chẳng hạn, nếu bạn muốn theo dõi quyền truy cập API, bạn có thể tăng nguyên tử một số bộ đếm người dùng như thế này

quầy. js

redis.put('key', 'value');
0

Ở đây, chúng tôi đang xuất một hàm có tên là

var redis = require('redis');module.exports = redis.createClient();
30 mà khách hàng gọi khi họ muốn đếm số lần truy cập API của một người dùng cụ thể. Hàm này tạo một giao dịch
var redis = require('./redis');redis.set('some key', 'some value');  
redis.expire('some key', 2);
setInterval(function() {
redis.get('some key', function(err, value) {
if (err) {
throw err;
}
if (value) {
console.log('value:', value);
}
else {
console.log('value is gone');
process.exit();
}
});
}, 1e3);
6 mang một số lệnh
var redis = require('redis');module.exports = redis.createClient();
32. Đối với mỗi lệnh này, khóa cơ sở luôn giống nhau – và được tạo riêng cho ID người dùng đã cho. Mỗi khóa thuộc tính sau đó được soạn dựa trên ngày hiện tại. Ví dụ: nếu ngày hiện tại là
var redis = require('redis');module.exports = redis.createClient();
33, điều này sẽ tăng số lượng bộ đếm có tên là
var redis = require('redis');module.exports = redis.createClient();
34,
var redis = require('redis');module.exports = redis.createClient();
35,
var redis = require('redis');module.exports = redis.createClient();
36,
var redis = require('redis');module.exports = redis.createClient();
33 và
var redis = require('redis');module.exports = redis.createClient();
38, tất cả đều nằm trong bản ghi bộ đếm dành riêng cho người dùng. Bằng cách này, bạn sẽ có các thùng truy cập cho mỗi ngày, tháng và năm, cũng như tổng cộng

Bạn sẽ phải cẩn thận khi duy trì các khóa bên trong mỗi Hash. Sau một thời gian, số lượng khóa cho mỗi người dùng đang hoạt động sẽ tăng lên, chiếm bộ nhớ Redis và tăng độ trễ hoạt động

danh sách

Redis có một loại thú vị khác. danh sách. Một danh sách trong Redis được triển khai nội bộ dưới dạng danh sách được liên kết, điều đó có nghĩa là việc chèn và xóa các phần tử khỏi nó không tốn kém

Ví dụ, điều này làm cho danh sách trở nên hữu ích để triển khai hàng đợi công việc. Bạn chèn công việc vào một đầu của danh sách và nhân viên lấy ra công việc từ đầu kia của danh sách. Hãy xem cách chúng ta có thể triển khai hàng đợi công việc bằng Redis

xếp hàng. js

redis.put('key', 'value');
1

Mô-đun

var redis = require('redis');module.exports = redis.createClient();
39 này xuất hai chức năng.
var redis = require('redis');module.exports = redis.createClient();
40 và
var redis = require('redis');module.exports = redis.createClient();
41. Cái đầu tiên làm nhiệm vụ đẩy các hạng mục công việc cho công nhân. Cái thứ hai là để công nhân bật công việc khỏi hàng đợi

Đây là một số mã thực hiện mô-đun này

queue_test. js

redis.put('key', 'value');
2

Tập lệnh này ở trên chèn 10 mục công việc vào hàng đợi. Sau khi tất cả chúng được chèn vào, nó sẽ bật chúng ra ngoài. Nếu không còn công việc nào nữa, nó sẽ đợi một giây trước khi thử bật một mục khác. Nếu không, nó sẽ cố gắng bật một cái khác ngay sau đó. Bạn có thể thực thi tập tin này

redis.put('key', 'value');
3

Tránh bỏ phiếu

Trong giải pháp cuối cùng này, các công nhân phải thăm dò ý kiến ​​​​của Redis cho công việc, điều này thật xấu xí, gây ra một chút chi phí và cũng dễ bị lỗi. Thay vào đó, kết nối máy khách Redis có thể sử dụng một trong các lệnh pop chặn danh sách để chặn trên danh sách khi không có phần tử nào. Với kiến ​​thức mới này, đây là cách chúng tôi sẽ triển khai lại mô-đun hàng đợi

queue_block. js

redis.put('key', 'value');
4

Ở đây, thay vì hiển thị hàm

var redis = require('redis');module.exports = redis.createClient();
41, chúng tôi hiển thị hàm tạo cho worker. Hàm tạo này nhận một hàm sẽ được gọi khi một mục công việc được bật lên hoặc khi xảy ra lỗi khi thực hiện nó

Bạn có thể thấy ở đây chúng tôi tạo một kết nối Redis cho mỗi worker. Điều này là do cửa sổ bật lên chặn kết nối, chỉ trả lời khi hết thời gian chờ nhất định hoặc khi một mục được bật lên

Không mất công

Một vấn đề có thể phát sinh từ bất kỳ triển khai hàng đợi công việc nào trước đó là công việc có thể bị mất nếu quy trình worker ngừng hoạt động. Nếu một công nhân chết trong khi xử lý một số công việc, thì phần công việc đó đã xuất hiện từ Redis và chúng tôi đã mất nó. Trong một số ứng dụng, điều này có thể không thành vấn đề nếu hiếm khi xảy ra;

“Thông thường, công việc phải được thực hiện nhiều nhất một lần hay ít nhất một lần. Nếu bạn phải thực hiện công việc ít nhất một lần, thì các hoạt động phát sinh từ công việc này phải là bình thường. nghĩa là, nếu cùng một hoạt động xảy ra nhiều lần, nó sẽ mang lại kết quả như nhau. Một ví dụ về điều này là hoạt động tuyên truyền thay đổi mật khẩu người dùng sang hệ thống nước ngoài. Sẽ không có vấn đề gì nếu thay đổi được lan truyền nhiều lần, vì nó sẽ mang lại kết quả tương tự, đó là đặt mật khẩu trong một hệ thống nước ngoài

Thường có một cách để thực hiện các thao tác thực thi chính xác một lần và thường liên quan đến việc tạo một mã định danh thao tác duy nhất và đảm bảo thao tác tương tự không được áp dụng hai lần. ”

Hãy xem cách chúng ta có thể tạo một hệ thống như vậy bằng hàng đợi Redis. Trước tiên, bạn sẽ cần cài đặt

var redis = require('redis');module.exports = redis.createClient();
43 này để tạo ID duy nhất

redis.put('key', 'value');
5

Chúng tôi hiện đã sẵn sàng để tạo một phiên bản hàng đợi an toàn hơn

queueblocksafe. js

redis.put('key', 'value');
6

Ở đây, hàm

var redis = require('redis');module.exports = redis.createClient();
44 của chúng tôi sử dụng lệnh
var redis = require('redis');module.exports = redis.createClient();
45, lệnh này bật nguyên tử từ một danh sách và đẩy vào một danh sách khác. Điều này đảm bảo rằng chúng tôi luôn có công việc trong Redis khi nó đang được xử lý. Khi worker xử lý xong mục, nó gọi hàm gọi lại (
var redis = require('redis');module.exports = redis.createClient();
46), hàm này sẽ xóa mục khỏi hàng đợi
var redis = require('redis');module.exports = redis.createClient();
47

Bây giờ, để khôi phục từ các công nhân đã chết, một quy trình có thể chịu trách nhiệm xem qua danh sách

var redis = require('redis');module.exports = redis.createClient();
47 và sắp xếp lại các hạng mục công việc đã vượt quá thời gian thực hiện nhất định

“Một điều cần lưu ý là, trong trường hợp có sự cố về tải trọng mà công nhân không đủ năng lực để tiêu thụ sản phẩm kịp thời, thì các hạng mục công việc có thể hết thời gian chờ và được yêu cầu, chỉ làm cho vấn đề về tải trọng. . Để tránh điều này, bạn nên a) đặt thời gian chờ đủ dài và b) ghi lại mọi sự kiện được yêu cầu và theo dõi tần suất của nó để bạn được cảnh báo khi nó quá cao. ”

bộ

Redis có các loại dữ liệu khác cho phép nhiều giá trị. Bộ Redis cho phép bạn lưu trữ nhiều giá trị chưa sắp xếp. Chúng cũng cho phép bạn nhanh chóng kiểm tra tư cách thành viên hoặc tính giao của hai tập hợp

Các bộ thường được sử dụng để nhóm các bản ghi. Chẳng hạn, giả sử rằng ứng dụng của bạn có một số nhóm người dùng. một cho người dùng đã đăng ký, một cho người dùng trả tiền, một cho người kiểm duyệt và một cho quản trị viên. Sau đó, chúng tôi có thể tạo một mô-đun để quản lý thuộc về các nhóm này

user_sets. js

redis.put('key', 'value');
7

Ở đây, chúng tôi đang sử dụng một số chức năng có tiền tố s của Redis để quản lý các bộ.

var redis = require('redis');module.exports = redis.createClient();
49 thêm thành viên vào nhóm và
var redis = require('redis');module.exports = redis.createClient();
50 sử dụng
var redis = require('redis');module.exports = redis.createClient();
51 để xóa thành viên khỏi nhóm. Chúng tôi cũng có thể kiểm tra xem một người dùng nhất định có thuộc một nhóm nhất định hay không. Chúng tôi có thể sử dụng điều này để xác minh xem người dùng được cấp có quyền thực hiện một số hoạt động hợp lý hay không

usersetexample. js

redis.put('key', 'value');
8

“Truy vấn

var redis = require('redis');module.exports = redis.createClient();
52 Redis có chi phí thời gian cố định, làm cho nó rất hiệu quả để kiểm tra xem một thành viên nhất định có thuộc một tập hợp nhất định hay không. Trong trường hợp của chúng tôi, điều này làm cho nó hiệu quả hơn, chẳng hạn như kiểm tra xem người dùng có thuộc nhóm người dùng nhất định hay không trước khi thực hiện một thao tác đặc quyền

Thêm một thành viên vào một tập hợp là một hoạt động bình thường. theo định nghĩa, một tập hợp sẽ không chứa các mục lặp lại. ”

Bây giờ chúng ta có thể chạy ví dụ này

redis.put('key', 'value');
9

tập hợp giao nhau

Bộ Redis cho phép bạn tính toán giao điểm. được cung cấp hai hoặc nhiều bộ, Redis có thể cho bạn biết thành viên nào là chung cho tất cả chúng. Chẳng hạn, chúng tôi có thể tính toán người dùng nào vừa là người kiểm duyệt vừa là người dùng trả tiền

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
0Bộ đã sắp xếp

Redis giữ các phần tử trong một tập hợp không theo thứ tự cụ thể. thứ tự mà bạn thêm chúng không nhất thiết phải là thứ tự mà Redis truy xuất chúng, làm cho chúng rất hữu ích cho các hoạt động khác liên quan đến tư cách thành viên

Nếu bạn cần các bộ được sắp xếp, Redis sẽ hỗ trợ bạn. có một nhóm các hoạt động có tiền tố Z đến giải cứu bạn

Mỗi phần tử của một tập hợp có một số điểm, là một số nguyên tự nhiên. Tất cả các phần tử được lưu trữ, sắp xếp và lập chỉ mục theo giá trị này, điều đó có nghĩa là bạn có thể truy xuất tất cả các phần tử trong một phạm vi điểm, tất cả được sắp xếp theo điểm

Giả sử rằng bạn đang chạy một trò chơi thời gian thực hợp tác trực tuyến và bạn muốn giữ thứ hạng điểm số cho mỗi trò chơi nhất định. Mỗi người chơi có một số điểm có thể tăng hoặc giảm và bạn muốn trình bày một bảng xếp hạng cập nhật với số điểm đó. Hãy tạo một mô-đun để quản lý điều đó

game_scores. js

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
1

Mô-đun này xuất hai chức năng. Cái đầu tiên, tên là

var redis = require('redis');module.exports = redis.createClient();
53, chấp nhận tên của một trò chơi, tên của một người chơi và một con số;

“Nếu người chơi trong phòng đó không tồn tại, nó sẽ được tạo bởi Redis với số điểm là 0. ”

Hàm thứ hai có tên là

var redis = require('redis');module.exports = redis.createClient();
54 và cung cấp cho bạn thứ hạng của một trò chơi nhất định. Ở đây, chúng tôi đang sử dụng truy vấn
var redis = require('redis');module.exports = redis.createClient();
55 Redis trả về một loạt các phần tử trong tập hợp đó, được sắp xếp theo thứ tự ngược lại của điểm số. Nếu chúng tôi muốn điều này trả về người dùng có số điểm thấp nhất trước tiên, chúng tôi sẽ sử dụng
var redis = require('redis');module.exports = redis.createClient();
56 để thay thế. Chúng tôi đang yêu cầu mọi phần tử của tập hợp bằng cách chỉ định
var redis = require('redis');module.exports = redis.createClient();
57 là phạm vi tối thiểu và
var redis = require('redis');module.exports = redis.createClient();
58 là phạm vi tối đa. Đặt giá trị lớn nhất là
var redis = require('redis');module.exports = redis.createClient();
58 làm cho phạm vi không có giới hạn trên, trả về hiệu quả tất cả các phần tử của tập hợp đó

Chúng tôi cũng chuyển vào tùy chọn

var redis = require('redis');module.exports = redis.createClient();
60, giúp Redis xen kẽ các điểm số trong phản hồi (một phần tử mảng cho mục nhập, một phần tử mảng cho điểm số, v.v. ). Ở đây, chúng tôi đang phân tích phản hồi và xây dựng một mảng xếp hạng phù hợp hơn trong đó mỗi phần tử có thuộc tính
var redis = require('redis');module.exports = redis.createClient();
61 và thuộc tính
var redis = require('redis');module.exports = redis.createClient();
53

Bây giờ chúng ta có thể mô phỏng một trò chơi bằng mô-đun này

gamescoresví dụ. js

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
2

Ở đây, chúng tôi đang tăng ngẫu nhiên điểm số của một người chơi ngẫu nhiên cứ sau 100 mili giây. Chúng tôi cũng đang in thứ hạng hiện tại của trò chơi mỗi giây

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
3Pub-sub

Bên cạnh tất cả các khóa-giá trị, danh sách, hàng đợi, loại tập hợp và hoạt động này, bạn cũng có thể sử dụng Redis để quản lý giao tiếp giữa các quá trình. Redis cung cấp mô hình đăng ký xuất bản trên các kênh được đặt tên cho phép người tạo tin nhắn và người tiêu dùng tin nhắn giao tiếp bằng cách sử dụng Redis làm nhà môi giới tin nhắn

Để xuất bản tin nhắn lên một kênh, bạn sử dụng lệnh

var redis = require('redis');module.exports = redis.createClient();
63, chuyển tên kênh và chuỗi tin nhắn

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
4

Bên cạnh các chuỗi trần, bạn cũng có thể xuất bản các đối tượng phức tạp bằng cách mã hóa JSON cho chúng

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
5

Để nhận tin nhắn, bạn phải dành riêng một kết nối Redis cho nó, bật chế độ người đăng ký bằng cách đưa ra lệnh

var redis = require('redis');module.exports = redis.createClient();
64 hoặc
var redis = require('redis');module.exports = redis.createClient();
65. Từ thời điểm đó, kết nối chỉ cho phép các lệnh thay đổi bộ đăng ký. Hãy xem điều này trong hành động

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
6

Ở đây chúng tôi đang đăng ký hai kênh có tên là “một số kênh” và “một số kênh khác”. Mỗi khi một thông báo được xuất bản trong Redis tới bất kỳ kênh nào trong số này, Redis sẽ phân phối thông báo tới tất cả các kết nối đang hoạt động có đăng ký kênh này

Như bạn có thể thấy từ ví dụ trước, bạn có thể tự động thêm đăng ký vào kết nối. Bạn cũng có thể tự động xóa đăng ký khỏi kết nối bằng cách gọi

var redis = require('redis');module.exports = redis.createClient();
66

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
7

Nếu bạn muốn nhận các đối tượng được mã hóa JSON phức tạp thay vì các chuỗi, bạn có thể phân tích cú pháp chuỗi như thế này

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
8Bộ phát phân tán

Nút có mẫu tương tự như Redis Pub-sub. Trình phát sự kiện. Trình phát sự kiện cho phép bạn tách trình tạo sự kiện khỏi trình tiêu thụ sự kiện, nhưng tất cả đều hoạt động trong cùng một quy trình Node. Chúng tôi có thể thay đổi nó để làm cho nó hoạt động giữa các quy trình

phân phối_emitter. js

redis.put('key', 'value', function(err) {  
if (err) {
console.error('error putting key:', err)
}
else {
console.log('key saved with success');
}
});
9

Ở đây chúng tôi đã tạo một mô-đun chỉ xuất một chức năng. một hàm tạo cho trình phát phân tán của chúng tôi, trả về một trình phát sự kiện đã sửa đổi

Khi tạo bộ phát phân tán, chúng tôi bắt đầu bằng cách thiết lập hai kết nối Redis. Một kết nối đóng vai trò là kết nối của nhà xuất bản và kết nối còn lại đóng vai trò là kết nối dành riêng cho người đăng ký. Điều này phải như thế này vì giao thức Redis. khi kết nối Redis chuyển sang chế độ thuê bao, nó không thể phát ra các lệnh khác với các lệnh thay đổi đăng ký

Sau đó, chúng tôi gọi

var redis = require('redis');module.exports = redis.createClient();
67 trên mỗi kết nối này. Điều này đảm bảo quy trình Nút không thoát chỉ vì chúng tôi có một trong các kết nối máy khách này đang mở

Sau đó, chúng tôi tiếp tục lắng nghe các sự kiện

var redis = require('redis');module.exports = redis.createClient();
68 trên mỗi kết nối Redis, mà chúng tôi chỉ truyền tới trình phát sự kiện được trả lại. Điều này cho phép khách hàng lắng nghe và xử lý các lỗi dành riêng cho Redis

Chúng tôi cũng lắng nghe các sự kiện

var redis = require('redis');module.exports = redis.createClient();
69 mà ứng dụng khách Redis phát ra khi các sự kiện đến từ hệ thống Redis Pub-sub thông qua kết nối ứng dụng khách. Khi điều này xảy ra, chúng tôi chỉ truyền sự kiện vào trình phát sự kiện cục bộ, cho phép người đăng ký trình phát sự kiện nhận được sự kiện đó

Tiếp theo, chúng tôi sửa đổi bộ phát sự kiện được trả về, thay thế các phương thức

var redis = require('redis');module.exports = redis.createClient();
70,
var redis = require('redis');module.exports = redis.createClient();
71,
var redis = require('redis');module.exports = redis.createClient();
72 và
var redis = require('redis');module.exports = redis.createClient();
73. Khi phát sự kiện, thay vì phát cục bộ, chúng tôi chỉ xuất bản sự kiện lên Redis, sử dụng tên sự kiện làm tên kênh

Chúng tôi cũng bọc các phương thức

var redis = require('redis');module.exports = redis.createClient();
71 và
var redis = require('redis');module.exports = redis.createClient();
72, được sử dụng để nghe các loại sự kiện. Khi bất kỳ sự kiện nào trong số này được gọi, nếu đó là lần đăng ký đầu tiên cho loại sự kiện cụ thể này, chúng tôi sẽ đăng ký kênh tương ứng trên Redis. Sau đó, chúng tôi trở lại hành vi mặc định, đó là thêm chức năng nghe vào Redis

Tương tự, chúng tôi bọc phương thức

var redis = require('redis');module.exports = redis.createClient();
73 để nắm bắt trường hợp khi không còn người nghe nào cho một loại sự kiện cụ thể, trong trường hợp đó, chúng tôi hủy đăng ký kênh tương ứng trên kết nối máy khách Redis của mình

Chúng tôi giữ xung quanh các phương thức cũ của trình phát sự kiện trong biến

var redis = require('redis');module.exports = redis.createClient();
77 để chúng tôi có thể gọi chúng từ bên trong các phương thức của trình bao bọc

Cuối cùng, chúng tôi triển khai một phương thức cụ thể

var redis = require('redis');module.exports = redis.createClient();
78 để đóng kết nối Redis

Bây giờ, hãy tạo một mô-đun máy khách để khởi tạo hai trình phát phân tán, sử dụng Redis để liên lạc giữa chúng, như sẽ xảy ra nếu chúng ở trong hai quy trình riêng biệt

được phân phối_emitter_example. js

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
0

Mô-đun máy khách mẫu này tạo hai bộ phát phân tán này. Cái đầu tiên đăng ký hai loại sự kiện, in ra những sự kiện này khi chúng đến. Cái thứ hai phát ra hai loại sự kiện này mỗi giây. Tải trọng của sự kiện chỉ là dấu thời gian. Hãy chạy cái này

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
1

Cẩn thận với điều kiện cuộc đua

Trình phát sự kiện phân tán này hoạt động khác với trình phát sự kiện thông thường theo một cách cơ bản. nó tuyên truyền các sự kiện bằng cách thực hiện I/O. Trong Node, I/O là một hoạt động không đồng bộ, trong khi tất cả các hoạt động điển hình của trình phát sự kiện chỉ là cục bộ và đồng bộ. Điều này có tác động đến thời gian cho các quy trình cục bộ. Chẳng hạn, hãy xem xét đoạn mã sau bằng cách sử dụng bộ phát sự kiện bình thường

local_event_emitter. js

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
2

Chạy này sẽ mang lại, như mong đợi

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
3

Tốt, tất cả đều bình thường. Bây giờ, hãy thử thay thế bộ phát sự kiện bằng một trong những bộ phát phân tán của chúng tôi

được phân phốievenemitter_race. js

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
4

Hãy thử chạy phiên bản này sau đó

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
5

Quá trình chỉ thoát mà không xuất ra bất cứ thứ gì. Điều này có nghĩa là, khi chúng ta gọi phương thức

var redis = require('redis');module.exports = redis.createClient();
72, trình phát phân tán sẽ đăng ký kênh lần đầu tiên. Nhưng điều đó liên quan đến một số I/O, vì vậy điều này không được thực hiện ngay lập tức. lệnh phải đi đến lớp mạng, phải được Redis nhận, phân tích cú pháp và thực thi, sau đó phản hồi sẽ quay trở lại Node. Tuy nhiên, trước khi tất cả I/O này xảy ra, chúng tôi đã phát ra một sự kiện (dòng cuối cùng của tệp trước đó). Sự kiện này cũng liên quan đến I/O, cũng không đồng bộ. Điều xảy ra là cả hai lệnh đang chạy đua để đến được Redis bằng hai kết nối máy khách khác nhau. Nếu lệnh
var redis = require('redis');module.exports = redis.createClient();
63 đến Redis trước lệnh
var redis = require('redis');module.exports = redis.createClient();
64, khách hàng của chúng tôi sẽ không bao giờ nhìn thấy sự kiện đó

Để xem chính xác chuỗi sự kiện trong Redis, chúng ta có thể sử dụng một mẹo nhỏ là sử dụng ứng dụng khách dòng lệnh Redis đi kèm với Redis. Với nó, bạn có thể theo dõi máy chủ Redis để kiểm tra lệnh nào đang được ban hành

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
6

Bây giờ bạn có thể thực thi tập lệnh nút trước đó và quan sát lệnh nào xảy ra trên Redis

redis.get('key', function(err, value) {  
if (err) {
console.error('error getting key:', err);
}
else {
console.log('key has the value %s', value);
}
});
7

của bạn đi. lệnh

var redis = require('redis');module.exports = redis.createClient();
82 đến sau lệnh
var redis = require('redis');module.exports = redis.createClient();
83, thua cuộc đua

“Điều này dùng để minh họa rằng cơ chế Pub-sub không phải là hàng đợi liên tục. người nghe sẽ chỉ nhận được các sự kiện mới sau khi yêu cầu đăng ký được máy chủ xử lý chứ không phải trước đó. Ghi nhớ điều này có thể sẽ giúp bạn tiết kiệm rất nhiều đau đầu trong tương lai. ”

Viết bởi Pedro Teixeira (trích từ Cơ sở dữ liệu-Tập I, sê-ri Mô hình nút) — xuất bản cho YLD

Làm cách nào để lấy dữ liệu từ Redis NodeJS?

Tạo phiên mới. js trong thư mục gốc với nội dung sau. const express = require('express'); . tạoClient();

Redis làm việc với NodeJS như thế nào?

Redis, một cơ sở dữ liệu trong bộ nhớ lưu trữ dữ liệu trong bộ nhớ máy chủ, là một công cụ phổ biến để lưu trữ dữ liệu vào bộ đệm. Bạn có thể kết nối với Redis trong Node. js sử dụng mô-đun nút-redis, cung cấp cho bạn các phương thức truy xuất và lưu trữ dữ liệu trong Redis .