# 内存缓存redis
# 一、redis介绍
Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。
Redis 与其他 key - value 缓存产品有以下三个特点:
- Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
- Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
- Redis支持数据的备份,即master-slave模式的数据备份。
# redis优势
- 性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
- 丰富的数据类型 – Redis支持二进制的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
- 原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
- 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
# redis安装
# 二、redis数据类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
# String(字符串)
string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。
string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。
# Hash(哈希)
Redis hash 是一个键值对集合。Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
# List(列表)
Redis 列表是简单的字符串双向链表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。应用场景:最新消息排行等功能(比如朋友圈的时间线)和消息队列。
# Set(集合)
Redis 的 Set 是 string 类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。集合提供了求交集、并集、差集等操作。应用场景:共同好友、利用唯一性,统计访问网站的所有独立ip、好友推荐时,根据tag求交集,大于某个阈值就可以推荐。
# zset(有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。数据插入有序集合时,已经进行天然排序。应用场景:排行榜、带权重的消息队列。
# 三、node操作redis
var redis = require('redis')
// 创建redis客户端
var client = redis.createClient(6379, '127.0.0.1')
client.on('error', (err) => {
console.log('Error ' + err);
});
// 1、字符串
client.set('color', 'red', redis.print);
client.get('color', (err, value) => {
if (err) throw err;
console.log('Got: ' + value)
client.quit();
})
// 2、哈希表
client.hmset('kitty', {
'age': '2-year-old',
'sex': 'male'
}, redis.print);
client.hget('kitty', 'age', (err, value) => {
if (err) throw err;
console.log('kitty is ' + value);
});
// 遍历kitty
client.hkeys('kitty', (err, keys) => {
if (err) throw err;
keys.forEach((key, i) => {
console.log(key, i);
});
client.quit();
});
// 3、列表
// lpush向链表中添加值
client.lpush('tasks', 'Paint the house red.', redis.print);
client.lpush('tasks', 'Paint the house green.', redis.print);
// lrange获取参数start和end范围内的链表元素, 参数end为-1,表明到链表中最后一个元素。
client.lrange('tasks', 0, -1, (err, items) => {
if (err) throw err;
items.forEach((item, i) => {
console.log(' ' + item);
});
client.quit();
});
// 4、集合
// 往集合添加元素
client.sadd('ip', '192.168.3.7', redis.print);
client.sadd('ip', '192.168.3.7', redis.print);
client.sadd('ip', '192.168.3.9', redis.print);
client.smembers('ip', (err, members) => {
if (err) throw err;
console.log(members);
client.quit();
});
// 5、有序集合
// 添加元素,第一个参数是key,后面的是元素的score和元素的值
client.zadd(['db', 0, 'mysql', 1, 'mongo', 2, 'redis'])
client.zrange('db', 0, 2, (err, data) => {
if (err) throw err;
console.log(data);
client.quit();
})
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# 四、redis实现排行榜
var redis = require('redis'),
RDS_PORT = 6379, //端口号
RDS_HOST = '127.0.0.1', //服务器IP 要连接的A服务器redis
//RDS_PWD = '123456', //密码
RDS_OPTS = {}, //设置项
redisClient = redis.createClient(RDS_PORT, RDS_HOST, RDS_OPTS);
// client.auth(RDS_PWD,function(){
// console.log('通过认证');
// });
redisClient.on('connect', async function () {
console.log('==Redis== Connect');
//按照 Score1,Key1,Score2,Key2,Score3,Key3方式初始化的
var vals = [13, 1, 12, 2, 14, 3, 20, 4]
console.log("==Jain== 4: vals: " + vals)
await redisClient.zadd('mysort', vals, function (err, res) {
console.log("==Jain== 5.1")
if (err != null) {
console.log("==Jain== error is: ", err);
} else {
console.log(res);
}
});
//无穷大和无穷小的分数区间内,key排名情况
await redisClient.zrange('mysort', 0, -1, function (err, res) {
console.log("==Jain== 5.2")
if (err != null) {
console.log("==Jain== error is: ", err);
} else {
console.log(res);
}
});
//无穷大和无穷小的分数区间内,排名总数
await redisClient.zcount('mysort', -Infinity, Infinity, function (err, res) {
console.log("==Jain== 5.3")
if (err != null) {
console.log("==Jain== error is: ", err);
} else {
console.log(res);
}
});
//无穷大和无穷小的分数区间内,从大到小的排序
var args1 = ['mysort', '+inf', '-inf'];
await redisClient.zrevrangebyscore(args1, function (err, res) {
console.log("==Jain== 6.1")
if (err != null) {
console.log("==Jain== error is: ", err);
} else {
console.log(res);
}
});
//指定分数区间,指定查询数量,偏移指定位数后的排名
var max = 25, min = 1, offset = 0, count = 4;
var args2 = ['mysort', max, min, 'WITHSCORES', 'LIMIT', offset, count];
await redisClient.zrevrangebyscore(args2, function (err, res) {
console.log("==Jain== 6.2")
if (err != null) {
console.log("==Jain== error is: ", err);
} else {
console.log(res);
}
});
//根据key去对应排名,从大到小,排名从0开始所以+1
var args3 = ['mysort', 4]
await redisClient.zrevrank(args3, function (err, res) {
console.log("==Jain== 7.1")
if (err != null) {
console.log("==Jain== error is: ", err);
} else {
console.log(res);
}
});
return
});
redisClient.on('ready', function (err) {
console.log('==Redis== Ready');
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
← 内存缓存memcache React核心 →