redis

101 阅读6分钟

Redis

  • 开源、免费
  • 高性能的key-value数据库
  • 原子性:所有操作要么都成功,要么都失败,失败完全不执行
  • 支持发布订阅、过期自动删除,所以可以做缓存

mac安装

  • brew install redis
  • 配置文件地址: /usr/local/etc/redis.conf
  • 启动:brew services restart redis, 默认端口6379

命令窗口

  • redis-cli 进入交互命令窗口

配置

  • 配置文件地址:/usr/local/etc/redis.conf
  • port 端口,默认6379
  • databases 数据库个数 默认16个
  • rdbcompression 是否支持压缩
  • dbfilename 文件存储名
  • dir 文件存储目录

设置配置

  • 如果直接修改conf文件的话需要重启redis才生效
  • 也支持在交互窗口通过命令修改,通过CONFIG关键字,小写也行,不区分大小写
  • 设置端口 CONFIG set port xxxx
  • 设置密码 CONFIG SET requirepass xxx
    • 再次进入操作的话就会提示NOAUTH Authentication required.
    • 登录方式:AUTH xxx

常用命令

基础命令

  • publish 事件名 参数
    • 执行事件,实现多操作联动
  • SET key value
    • 设置name和值
    • 如key存在,会清除原本身上附带的信息,如倒计时
  • GET key
    • 获取key对应的值
    • 查不到就是(nil)
  • KEYS *
    • 查询所有key
    • 查不到就是(empty array)
  • KEYS key
    • 存在就返回key,不存在就是(empty array)
  • KEYS n*e
    • 查询以n开头以e结尾的所有key
  • SELECT value
    • 切换到16个数据库中的某个,value在0-15之间
    • 每个数据库之间的数据不相通
    • 默认第1个,SELECT 0
  • FLUSHDB
    • 清除当前数据库的所有数据
  • FLUSHALL
    • 清除所有数据库的数据
  • EXISTS key
    • 查询是否key存在,存在就返回1,否则为0
    • 可有多个key,返回的结果为存在个数累加,例如:EXISTS ne name s nne中假设只有ne 和 nne存在,那么返回2
  • RENAME 现有key 预计修改key
    • 将a名称修改为b
  • DEL key
    • 删除某个key
    • 可同时删除多个key,以空格间隔即可,删除成功会返回删除个数
  • SETNX key value
    • 如果key存在,就返回0,代表不操作,如果不存在,返回1,写入value
  • GETRANGE key start end
    • 截取中间某部分的字段
    • 包含star与end
    • 例子:假设name为123456,执行GETRANGE name 0 2,得到结果012
  • STRLEN key
    • 查询某个key对应的value的长度
  • INCR key
    • 数字累加,将当前key的value+=1
  • INCRBY key number
    • 自定义累加数量,如:INCRBY PV 5,设置pv本次+=5
  • DECR key
    • 数字递减,将当前key的value-=1
  • DECRBY key number
    • 自定义当前减的数量,与INCRBY相反
  • EXPIRE key number
    • 设置number秒后自动删除当前key
  • TTL key
    • 查询还有多少秒后删除当前key
    • 特殊记忆:-1代表没有设置倒计时、-2代表key不存在
  • PERSIST key
    • 将某个key持久化,不设置倒计时的话,默认就是持久化
    • 常用来取消倒计时,比如某个key设置了倒计时,但中途不想删了,那么使用PERSIST来取消
  • TYPE key
    • 查询key的类型,string、hash、list、set、none

同时操作多个元素命令

  • MSET a 1 b 2
    • 设置a=1,b=2
  • MGET a b
    • 获取a和b的value

hash哈希表

  • 上述为字符串的设置
  • 哈希为命令前缀加H表示哈希
  • 例如
// 设置,哈希的设置可以同时设置多个
HSET user name cc age 11 address xxx
// 获取user.name 
// HGET只能获取单个
HGET user name

// HMGET 获取多个
HMGET  user name age address
// 查询有几个key
HLEN user
  • HKEYS key
    • 获取当前哈希表的所有key,可以理解为Object.keys
  • HGETALL key
    • 获取表中的所有key和value,n为key,2n为value

list链表

  • 字符串命令前缀加L
  • LPUSH key value
    • 在key的左侧倒序放入哪些值,value可以有多个
  • RPUSH key value
    • 在key的右侧放入哪些值,value可以有多个
  • LRANGE key 0 -1
    • 查询链表内所有项
  • LINDEX key index
    • 获取当前索引对应的值,索引从0开始
  • LSET key index value
    • 修改key中某个索引对应的值为value
  • LPOP key count
    • 从左侧删除key的几个值
  • RPOP key count
    • 从右侧删除key的几个值
// 在list左侧插入1 2 3
LPUSH list 1 2 3

// 查询
LRANGE key 0 -1
// 结果
1) "3"
2) "2"
3) "1"

// 右侧插入 7 8 9
RPUSH list 7 8 9
//查询
LRANGE list 0 -1
// 结果
1) "3"
2) "2"
3) "1"
4) "7"
5) "8"
6) "9"
// 查询长度
LLEN list
6
// 获取索引为1的值
LINDEX  list 1
// 2

set集合

  • 前缀+S
  • SADD key name1 name2 name3
    • 设置一个集合,存储了多个name,name可以有多个
    • 重复的话,后边的会覆盖前面
  • SMEMBERS key
    • 查询所有name
  • SCARD key
    • 查询name个数
  • SISMEMBER key name
    • 查询某个key是否存在key中
    • 存在就是1,否则为0
// 设置集合 tags,有4个name,a、b、c、d
SADD tags a b c d a
// 查询所有name
SMEMBERS tags
// 结果
1) "a"
2) "d"
3) "c"
4) "b"
// 查询name个数
SCARD tags
// 4
  • SINTER key key...
    • 求多个key的交集
    • key可以有多个
  • SDIFF key key
    • 求多个key的差集(key1比key2少的部分)
    • 两个key
  • SUNION key key ...
    • 求多个key的并集
  • SINTERSTORE C A B
    • 将A和B的交集存到C中

zset有序集合

  • Z开头
  • ZADD key 级别 name 级别 name ...
    • 会按照级别的大小排序,小的在前面,且先后有排名
  • ZRANGE key 0 -1
    • 查看所有name
  • ZRANGE key 0 -1 withscores
    • 查询name和级别,n为name,2n为级别
  • ZREVRANGE key 0 -1
    • 倒序查看所有name
  • ZRANGEBYSCORE key start end
    • 获取包含且排在在start~end之间的name
  • ZRANK key name
    • 获取name对应的级别

事务

  • MULTI
    • 开启事务
  • 然后正常输入命令
  • exec
    • 执行所有命令
    • 可以理解成固定脚本
127.0.0.1:6379> MULTI
//OK
127.0.0.1:6379(TX)> SET AAA 1
//QUEUED
127.0.0.1:6379(TX)> GET AAA
//QUEUED
//在这里故意使用错误语法,但并没有执行,所以不抛出异常
127.0.0.1:6379(TX)> SET BB == 1
//QUEUED
127.0.0.1:6379(TX)> exec
1) OK
2) "1"
3) (error) ERR syntax error

在node中使用

const { createClient } = require("redis");

const client = createClient({
  url: "redis://用户名:密码@127.0.0.1:6379",
});

/**
 * 设置key
 * @param {*} key
 * @param {*} value
 * @param {*} expire
 * @returns
 */
async function setValue(key, value, expire) {
  if (typeof expire === "undefined") {
    client.set(key, value);
  } else {
    return client.set(key, value, { EX: expire });
  }
}
/**
 * 获取key
 * @param {*} key
 * @returns
 */
async function getValue(key) {
  return client.get(key);
}
/**
 * 获取过期时间
 * @param {*} key
 * @returns
 */
async function getExpire(key) {
  return client.ttl(key);
}
(async () => {
 // 建立连接
  await client.connect();
  console.log("连接成功");
  //   await setValue("name", "cui", 3);
  const val = await getValue("name");
  console.log(val);
  console.log(await getExpire("name"));
  // 事件的订阅
  // 在item2里进入交互窗口,执行publish clear hahah,这里会收到haha
  client.subscribe("clear", function (value) {
    console.log(value);
  });
  // 断开连接
  //   return client.disconnect();
})();