关于redis:Redis基础

Redis介绍

概述

  • Redis是Remote Dictionary Server(近程数据服务)的缩写.

由意大利人antirez(Salvatore Sanfilippo)开发的一款内存高速缓存数据库,诞生于08年。

依据月度排行网站DB-Engines.com的数据显示,Redis是最风行的键值对存储数据库。

  • 该软件应用C语言编写,它的数据模型为key-value,

开源的,构建与内存的数据结构数据库,罕用作数据存储,缓存解决和音讯队列解决

  • 反对多种数据结构类型,

包含string(字符串)、hash(哈希)、list(链表)、set(汇合)、Zset(有序汇合)。

  • 为了保障效率数据都是缓存在内存中,它也能够周期性的把更新的数据写入磁盘或者把批改操作写入追加的记录文件。
  • 极高的读写性能,原子性操作

Redis能读的速度是110000次/s,写的速度是81000次/s 。

Redis所有单个命令的执行都是原子性的,这与它的单线程机制无关;

Redis命令的原子性使得咱们不必思考并发问题,能够不便的利用原子性自增操作 实现简略计数器性能;

应用缓存加重数据库的负载。

在开发网站的时候如果有一些数据在短时间之内不会发生变化,而它们还要被频繁拜访,为了进步用户的申请速度和升高网站的负载,就把这些数据放到一个读取速度更快的介质上(或者是通过较少的计算量就能够取得该数据) ,该行为就称作对该数据的缓存。

该介质能够是:文件、数据库、内存,内存介子常常用于数据缓存。

缓存的两种模式:

  • 页面缓存(磁盘缓存):常常用在CMS(content manage system)内存管理系统里边(Smarty缓存)

index.php ==== >index.html 就间接拜访index.html页面;

  • 数据缓存:常常会用在页面的具体数据里边

    应用场合及其劣势

  • 高性能缓存,最常见的利用场景
  • 多类型数据结构,适宜各种类型数据,
  • Redis分布式存储
  • 数据有生命周期,Redis的键能够设置过期时长,一段时间当前主动删除。
  • 高并发和海量数据的解决
  • 数据长久化,数据存储到硬盘外面,服务器断电不失落。

redis与memcache比拟

1、数据类型:

memcache反对的数据类型就是字符串,

redis反对的数据类型有字符串,哈希,链表,汇合,有序汇合。

2、长久化:

memcache数据是存储到内存外面,一旦断电,或重启,则数据失落。

redis数据也是存储到内存外面的,然而能够长久化,周期性的把数据给保留到硬盘外面,导致重启,或断电不会失落数据。

3、数据量:

memcahce一个键存储的数据最大是1M,

而redis的一个键值,存储的最大数据量是1G的数据量。

装置redis

#下载
wget http://download.redis.io/releases/redis-6.0.6.tar.gz
#解压
tar zxvf redis-6.0.6.tar.gz
#进入解压目录
cd redis-6.0.6

#无需配置,间接编译
make

若呈现如下提醒,则阐明未装置gcc

/bin/sh: cc: command not found
make[1]: * [adlist.o] Error 127
make[1]: Leaving directory `/root/redis-6.0.6/src’
make: * [all] Error 2

解决:yum -y install gcc

若呈现如下提醒

make[1]: * [server.o] Error 1

make[1]: Leaving directory `/root/redis-6.0.1/src’

make: * [all] Error 2

呈现这个问题须要先确认GCC的版本,命令如下:

gcc -v

发现CentOS7默认的gcc版本为4.8.5,装置Redis6.0须要将gcc版本升级到5.3以上,则降级gcc命令如下:

yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
 
#长期批改gcc版本
scl enable devtoolset-9 bash
#永恒批改gcc版本
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile

装置

#(装置编译后的文件)到指定目录:
make PREFIX=/usr/local/redis install

留神:
    PREFIX必须大写、同时会主动为咱们创立redis目录,并将后果装置此目录

装置实现后,会在redis的装置目录上面创立一个bin目录,该目录外面有5个文件。

redis-benchmark 命令性能测试命令

redis-check-aof和redis-check-rdb 日志检测工具

redis-server 是服务器端启动的命令

redis-cli 是客户端连贯服务器的命令

配置文件详解

从redis的解压目录外面把redis.conf配置文件复制到redis的装置目录上面(与bin目录同级)。

cp ~/redis-6.0.6/redis.conf /usr/local/redis

1、redis默认不是以守护过程的形式运行,能够通过该配置项批改,应用yes启用守护过程

daemonize no // 改为 yes,让redis的过程在后盾执行,不占据以后终端。

2、当Redis以守护过程形式运行时,Redis默认会把pid写入/var/run/redis.pid文件,能够通过pidfile指定

pidfile /var/run/redis.pid

3、指定Redis监听端口,默认端口为6379,

port 6379

4、平安认证

requirepass 321612

留神:

        设置的明码是明文的,因而要对redis.conf配置文件,进行严格的受权。

5、外网php客户端连贯Linux的redis

开启redis-server后,redis-cli只能拜访到127.0.0.1,因为在配置文件中固定了ip,

bind 127.0.0.1   改为 #bind 127.0.0.1

protected-mode yes 改为 protected-mode no

redis从3.2版本后减少了protected-mode参数,protected-mode参数是为了禁止外网拜访redis,
如果启用了,则只能通过lookbackip(127.0.0.1)拜访redis,如果外网拜访redis,会报出异样。

启动

启动redis服务

语法:

    redis-server(写门路) redis.conf(写门路)
cd /usr/local/redis/bin
./redis-server ../redis.conf

启动redis客户端

语法: redis-cli -h 主机ip -p端口号

./redis-cli

PING命令,该命令用于检测redis服务是否启动

redis敞开服务

  • 断电、非正常敞开。容易数据失落

    ps -ef | grep redis
    kill -9 PID

  • 失常敞开、数据保留

    通过客户端进行shutdown,敞开redis服务

    exit
    /usr/local/redis/bin/redis-cli shutdown    

装置php的redis扩大

CentOS7为php7.2装置php-redis扩大

yum -y install php-pecl-redis

凋谢6379端口

firewall-cmd --zone=public --add-port=6379/tcp --permanent

firewall-cmd --reload

selinux长期敞开(不必重启机器):

setenforce 0          #设置SELinux 成为permissive模式

php操作redis

$redis = new Redis();
$redis->connect('localhost');
$redis->auth('321612');

// 字符串类型
$redis->set('age',12);
$redis->set('username','libai');

//哈希类型
$redis -> hset('user:id:1', 'name', 'songjiang');
$redis -> hmset('user:id:2', ['name'=>'xiaohei','age'=>12,'email'=>'xiaohei@souhu.com']);

//链表类型
$redis -> lpush('user_list', '王刚');
$redis -> lpush('user_list', '宋江');
$redis -> lpush('user_list', '李白');

//字符串
$username = $redis->get('username');
$age = $redis->get('age');

//哈希
$data = $redis -> hgetall('user:id:2');

//链表
$info = $redis->lrange('user_list',0,-1);

案例: 记住明码谬误次数

$username = $_POST['username'];
$password = $_POST['password'];

$redis = new Redis();
$redis->connect('localhost');

// 构建键
$login_key = $username.'login_num';
$num = $redis->get($login_key);

if($num>=3){
    //设定过期工夫
    $redis->setTimeout($login_key,3600*24);
    exit('锁定账号');
}

// 明码
$pwd = '123456';

if ($password == $pwd) {
    echo 'login success';
} else {
    $redis->incr($login_key);
    echo '明码谬误!';
}

key命名标准

key 单词与单词之间以 : 离开

个别状况下:

第一段搁置我的项目名或缩写,如 project

第二段把表名转换为key前缀,如 user:

第三段搁置用于辨别区key的字段,对应mysql中的主键的列名,如 userid

第四段搁置主键值,如18,16

例:

user:id:3506728370            {id:3506728370,name:春晚,fans:12210947,blogs:6164,focus:83}

#表名:主键名:主键值:属性名    
user:id:3506728370:fans      12210947

user:id:3506728370:blogs     6164

user:id:3506728370:focus     83

string(字符串)

redis的string能够蕴含任何数据,包含序列化的对象、数组。

单个value值最大下限是1G字节,如果只用string类型,redis就能够被看做加上长久化个性(服务器重启之后,数据不失落)的memcache。

基本操作

  • set 增加/批改数据

    语法:

    set 键名称 值
    

    返回值:

    设置胜利返回OK,设置失败返回nil
    

    例:

    增加一个name="xiaoqian"的键值对
    set name xiaoqian
    
    留神:
        从新设置则间接笼罩。
    
  • get

    获取key对应的string值,如果key不存在返回nil

    语法:

    get key 
    
    如果key不是string类型,返回错误信息。
    
  • del 删除数据

    语法:

    del key
    
  • mset

    语法:

    mset key value [key value]
    
    同时设置多个key,如果key存在会笼罩,
    该命令是原子的,所有的键会同时设置胜利或失败,胜利返回OK
    

    例:

    mset name xiaohei age 12 email xiaohei@163.com
    
  • mget

    语法:

    mget key [key...]
    
    查问所有key的值
    

    返回值:

    列出所有键的值,绝不会执行失败,
    如果键是string类型,返回其值,
    如果键不存在或者不是string类型,返回nil
    

    例:

    mget name email title
    // xiaohei
    // xiaogei@163.com
    // nil
    
  • strlen 返回key的字符串长度
语法:
    strlen key 
    
返回值:
    如果key不存在返回0
    如果不是字符串类型,返回错误信息。

例:
    set age 300

    strlen age //3
  • append 追加信息到原始信息后部(如果原始信息存在就追加,否则新建)

    语法:

    append key value
    

    例:

    append age 200
    
    get age //300200

数值增减

  • incr

    对key的值做加加操作,每执行一次值加1,值类型要是数据类型。

    语法:

    incr key
    
    将key中存储的数字值增一操作,
    如果key不存在,则key的值会先被初始化为0,
    而后再执行incr操作,key的值必须是整型。
    

    例:age原先12

    incr age
    //13
    
  • incrby

    执行加法的命令,能够指定相加的值

    语法:

    incrby key 相加的值
    
  • decr(减1) decrby(减指定的值)

留神:

string在redis外部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算

redis所有的操作都是原子性的,采纳单线程解决所有业务,命令是一个一个执行的,因而无需思考并发带来的数据影响。

时效性

  • setex 设置生效工夫

    语法:

    setex key seconds value
    
    给一个键设置为字符串类型,并指定生存工夫(单位:秒),
    该命令是原子的,如果设置失败或指定生存工夫失败,会复原初始状态。
    

    返回值:

    如果设置胜利,返回OK,如果设置失败,返回错误信息。
    

    例:

    setex height 10 198

其余

  • setnx (判断键是否存在)

    语法:

    setnx key value
    
    如果key不存在,将其设置为字符串类型
    

    返回值:

    如果设置胜利,返回1,设置失败,返回0
    

    例:name曾经存在时,body不存在

    setnx name xiaobai
    // 0
    
    setnx body 1234
    //1
    
  • getset

    语法:

    getset key value
    
    原子的给一个key设置新值,并且将旧值返回,
    

    返回值:

    如果key不是字符串类型,返回一个谬误
    

    利用场景:

    比方获取计数器并且重置为0。
    

    例:

    get name
    //xiaohei
    getset name xiaohuihui
    //xiaohei
    get name
    //xiaohuihui

hash(哈希)

hash类型能够看成是具备key和value的容器,该类型非常适合存储对象信息,相似于关联数组。

一个存储空间保留多个键值对数据

基本操作

  • hset 设置哈希外面的field和value的值。

    语法:

    hset key field value
    

    例:

    hset user:id:1 name xiaobai
    
    hset user:id:1 age 12
    
    hset user:id:1 email xiaobai@sohu.com
    
  • hget 获取哈希外面的field的值

    语法:

    hget key 指定的field
    

    例:

    hget user:id:1 name
    //xiaobai
    
    hget user:id:1 age
    //12
    
  • hgetall 获取指定哈希中所有的field和value

    语法:

    hgetall key
    

    例:

    hgetall user:id:2
    //name
    //xiaohong
    //age
    //12
    //email
    //xiaohong@sohu.com
    
  • hdel 删除数据

    语法:

    hdel field1 [field2]
    
  • hmset 一次性设置多个field和value。

    语法:

    hmset key field1 value1 field2 value2    
    

    例:

    hmset user:id:2 name xiaohong age 12 email xiaohong@sohu.com
    
  • hmget 一次性获取 多个field的value

    语法:

    hmget key field1 field2......
    

    例:

    hmget user:id:2 name age email
    //xiaohong
    //12
    //xiaohong@souhu.com
    
  • hlen 获取哈希表中字段的数量

    语法:

    hlen key 
    

    例:

    hlen user:id:2
    //3
    

    留神:

    看的是field的数量
    
  • hexists 获取哈希表中是否存在指定的字段

    语法:

    hexists key field
    

    例:

    hexists user:id:2 age 

其余

  • hkeys 获取哈希表中所有的字段名

    语法:

    hkeys key 
    
  • hvals 获取哈希表中所有的字段值

    语法:

    hvals key
    
  • 设置指定字段的数值数据减少指定范畴的值

    hincrby key field increment

    hincrbyfloat key field increment

hash实现购物车

业务剖析

  • 仅剖析购物车的redis存储模型:增加、浏览、更改数量、删除、清空
  • 购物车与数据库间长久化同步(不探讨)
  • 购物车与订单间关系(不探讨)

    ​ 提交购物车:读取数据生成订单

    ​ 商家长期价格调整:隶属于订单级别

  • 未登录用户购物车信息存储(不探讨)

    ​ cookie存储

解决方案:

  • 以客户id作为key,每位客户创立一个hash存储构造存储对应的购物车信息
  • 将商品编号作为field,购买数量作为value进行存储
  • 增加商品:追加全新的field与value
  • 浏览:遍历hash
  • 更改数量:自增/自减,设置value值
  • 删除商品:删除field
  • 清空:删除key
hmset user:id:1 g1 100 g2 200
hmset user:id:2 g2 1 g4 7 g5 100

//增加商品
hset user:id:1 g3 5

//查看购物车
hgetall user:id:1

//删除商品
hdel user:id:1 g1

//更改数量
hincrby user:id:1 g3 100

以后设计仅仅是将数据存储到了redis中,并没有起到减速的作用,商品信息还须要二次查询数据库

  • 每条购物车中的商品记录保留成两条field
  • field1专用于保留购买数量

    • 命名格局:商品id:nums
    • 保留数据:数值
  • field2专用于保留购物车中显示的信息,蕴含文字描述,图片地址,所属商家信息等

    • 命名格局:商品id:info
    • 保留数据:json
hmset user:id:3 g1:nums 100 g1:info {……}
hmset user:id:4 g1:nums 100 g1:info {……}

以后设计有很大的冗余,商品信息反复存储了

  • 能够把商品信息做成独自的hash
hset user:id:3 g1:nums 200 
hsetnx goods:info g1:info {……}

hset user:id:4 g1:nums 100 
hsetnx goods:info g1:info {……}

hash实现抢购

销售手机充值卡的商家对挪动、联通、电信的30元、50元、100元商品推出抢购流动,每种商品抢购下限1000张

解决方案:

  • 将商家id作为key
  • 将参加抢购的商品id作为field
  • 将参加抢购的商品数量作为对应的value
  • 抢购时应用降值的形式管制产品数量
  • 理论业务中还有超卖等理论问题,这里不做探讨
hmset business:id:1 c30 1000 c50 1000 c100 1000

hincrby business:id:1 c50 -1

list(列表)

list 类型其实就是一个字符串的双向链表,依照插入程序排序。

能够增加一个元素到链表的头部(右边)或者尾部(左边),一个链表最多能够蕴含232 -1 个元素(4294967295,每个链表超过40亿个元素),

这使得list既能够用作栈,也能够用作队列。

利用场景:

粉丝列表
最新文章
音讯队列等

增加/批改

  • lpush 从链表的头部增加一个或多个元素

    语法:

    lpush key value1 [value2] 
    
    操作为原子性操作,如果key不存在,一个空列表会被创立并执行lpush操作。
    

    返回值:

    执行lpush命令后,列表的长度。
    

    例:

    lpush user_list libai
    //1
    lpush user_list lihei
    //2
    lpush user_list songjiang
    //3
    
  • rpush 从链表的尾部增加元素

    语法:

    rpush key value1 [value2] 
    

    例:

    rpush user_list wusong
    //5
    
    lrange user_list 0 -1
    //wuyong
    //dufu
    //lihei
    //libai
    //wusong
    
  • linsert 将元素插入到链表中某个元素之前或之后

    语法:

    linsert key before|after 链表中的某个元素 新的元素
    

    返回值:

    执行胜利,返回插入操作实现之后,列表的长度
    如果没有找到链表中的元素,返回-1
    如果链表不存在或空链表,返回0
    

    例:

    linsert user_list before lihei dufu
    //4
    
  • lset(改值) 批改链表中指定下标的元素。

    语法:

    lset key 下标 新值
    

    例:

    lset user_list 0 wuyong
    
    lrange user_list 0 -1
    //wuyong
    //dufu
    //lihei
    //libai

获取

  • lrange 获取链表外面的元素

    语法:

    lrange key start(索引) stop(索引)
    

    留神:

    如果开始下标是0,完结下标是-1,则返回链表中所有的元素。
    链表外面的元素是序号的(从0开始,头部开始),相似于索引数组。
    

    例:

    lrange user_list 0 -1
    //songjiang
    //lihei
    //libai
    
  • lindex 返回列表中指定下标的元素

    语法:

    lindex key index
    

    例:

    lindex user_list 2
    //lihei
    
  • llen 返回列表的长度

    语法:

    llen key
    

    例:

    llen user_list
    //5

获取并移除

  • lpop 删除并返回链表中头部的元素

    语法:

    lpop key 
    

    例:

    lpop user_list
    //wuyong
    
    lrange user_list 0 -1
    //dufu
    //lihei
    //libai
    //wusong
    
  • rpop 删除并返回链表尾部的元素

    语法:

    rpop key 

删除

  • lrem 删除链表中的元素

    语法:

    lrem key count value
    
    依据参数count的值,删除链表中与value相等的元素。
    count>0,
        从表头开始向表尾搜寻,删除与value相等的元素,数量为count。
    count<0,
        从表尾开始向表头搜寻,删除与value相等的元素,数量为count。
    count=0,
        删除表中所有与value相等的值。
    

    返回值:

    被删除的元素的数量。
    

    例:

    从尾部删一个
    lrange user_list -1 lihei        
    
  • ltrem 保留指定范畴的元素,其余的删除

    语法:

    ltrim 链表的名称 开始下标 完结下标 
    

    例:

    lrange user_list 0 -1
    //lihei
    //dufu
    //libai
    //wusong
    
    ltrim user_list 1 2
    //ok 
    
    lrange user_list 0 -1
    //dufu
    //libai 

阻塞数据获取

规定工夫内获取并移除数据

blpop key1 [key2] timeout

blpop list0 30

brpop key1 [key2] timeout


案例:一个网站中,想要获取最新登录的10个用户。

如果通过list链表实现以上性能,能够在list链表中只保留最新的10个数据,每进来一个新数据就删除一个旧数据。

每次就能够从链表中间接取得须要的数据。极大节俭各方面资源耗费。

例:
    lpush user_login songjiang 
    
    if (llen(user_login)>10) {
        //从尾部弹出元素
        rpop user_login
    }

    //查
    lrange user_login 0 -1

秒杀案例:

原理:

    应用redis链表中队列,进行pop操作,
    因为pop操作是原子的,即便有很多用户同时达到,也是顺次执行。
$redis = new Redis();
$redis->connect('127.0.0.1',6379); 
$redis->auth('321612');

//1、先将商品库存退出队列
//商品数量
$goods_num = 100;
//增加到队列
for ($i=0; $i < $goods_num; $i++) { 
    $redis -> lpush('goods_store',1); //理论存商品id
}
$redis = new Redis();
$redis->connect('127.0.0.1',6379); 
$redis->auth('321612');

//2、开始抢购
//设置库存的生效工夫
$redis->setTimeout('goods_store',30);
$redis = new Redis();
$redis->connect('127.0.0.1',6379); 
$redis->auth('321612');

//3、客户端执行下单操作,下单前判断redis队列库存量
$id = $redis->lpop('goods_store');
if(!$id){
    echo '抢购失败!';
    return;  
}

echo '抢购胜利!'; 
//跳转到下单页面,实现下单操作

案例:注册发邮箱

register.php

$username = $_POST['username'];
$email = $_POST['email'];
//实现注册,插入到mysql数据库

//发送邮件到邮箱,让用户激活

$redis = new Redis();
$redis->connect('127.0.0.1');
$redis->auth('321612');

//把发送邮件的操作增加到一个队列外面(异步操作)
$redis->lpush('email',json_encode(['email'=>$email,'username'=>$username]));
echo  'register success';

send_email.php

$redis = new Redis();
$redis->connect('127.0.0.1');
$redis->auth('321612');

//依据列表外面的队列执行发送邮件的操作
while(true){
    $info = $redis->lpop('email');
    
    //发送邮件
    
}

set(汇合)

redis 的 set 是string类型的无序汇合。

set元素最大能够蕴含(232-1)(整型最大值)个元素。

对于set汇合类型除了根本的增加、删除操作,其余有用的操作还蕴含汇合的取 并集(union),交加(intersection),差集(difference)。

sina公司的好友关注关系就大量应用了set汇合类型。

留神:

    每个汇合中的各个元素不能反复。

基本操作

  • sadd 向汇合中增加元素
语法:
    sadd key member1 [member2]

例:
    sadd libai_friend likui
    // 1
    sadd libai_friend xionger
    // 1
    sadd libai_friend xiongda
    // 1
    sadd libai_friend yangguo limochou
    // 2


  • smembers 获取汇合中的全副元素
语法:
    smembers key

例:
    smembers libai_friend
    //xiongda
    //xionger
    //limochou
    //likui
    //yangguo


  • srem 删除汇合中的元素

    语法:

    srem  key member1 member2
    
  • scard 获取汇合中元素的个数

    语法:

    scard 汇合名称
    

    例:

    scard libai_friend
    // 6 
    
    scard dufu_friend
    // 5        
    
  • sismember 判断汇合中是否蕴含指定数据

    语法:

    sismember key member

操作随机数据

  • srandmember 随机获取汇合中指定数量的数据

    语法:

    srandmember  key [count]
    

    例:

    sadd news n1    
    sadd news n2    
    sadd news n3    
    sadd news n4    
    
    srandmember news 2
    //n4
    //n1
    
    srandmember news 2
    //n2
    //n1
    
  • spop 随机获取汇合中的某个数据并将该数据移出汇合

    语法:

    spop  key
    

    例:

    spop news 
    //n5

交并差集

交加:两个汇合中共有的元素

差集:在第一个汇合外面有的,在第二个汇合外面没有的。

并集:两个汇合合并在一块,去掉重复部分

  • sinter 获取交加(在两个汇合中都存在的元素)

    语法:

    sinter key1 key2
    

    例:

    sinter libai_friend dufu_friend
    //xionger
    //likui
    
  • sunion 求并集(两个汇合合并后,去掉反复的元素)

    语法:

    sunion key1 key2 
    

    例:

    sunion libai_friend dufu_friend
    
  • sdiff 获取汇合中的差集(在汇合1中存在,不在汇合2中存在的元素)

    语法:

    sdiff key1 key2
    

    例:

    sdiff libai_friend dufu_friend
    
    sdiff dufu_friend libai_friend
  • 求两个汇合的交并差集并存储到指定汇合中

sinterstore destination  key1 key2

例:
    sinterstore u3 u1 u2


sunionstore destination  key1 key2

例:
    sunionstore u3 u1 u2


sdiffstore destination  key1 key2

例:
    sdiffstore u3 u1 u2
  • smove source destination key1 key2 将指定数据从原始汇合中挪动到指标汇合中
例:
    把u2的w1挪动到u1里
    smove u2 u1 w1

zset(sorted set: 有序汇合)

sorted set 是 set 的一个降级版本,在set的根底上减少了一个程序属性(权值),

这一属性在增加批改元素的时候能够指定,每次指定后,zset会主动从新按新的值调整程序。

留神:

增加进去的元素,会主动依据序号排序。

​ 只有元素不一样即可,有序汇合外面能够有雷同序号

​ 取值的时候,索引跟序号没关系

基本操作

  • zadd 向有序汇合中增加元素。如果该元素存在,则更新其序号。

    语法:

    zadd key score1 member1 [score2 member2]
    

    例:

    zadd zst1 23 xiaolong
    zadd zst1 67 libai
    zadd zst1 88 xiaolong   //元素存在,则更新其程序。
    zadd zst1 67 liubei     //能够有雷同序号
    
    
    
  • zrange 按序号升序获取有序汇合中的内容。

(把汇合排序后,返回名次[start, stop]的元素,默认是升序排列,withscores 是把score也打印进去)

语法:
    zrange key start stop [WITHSCORES] 

例:
    zrange zset1 0 -1 withscores 
    //xiaolonog
    //12
    //libai
    //23
    //liubei
    //23
    //xiaolong
    //45

留神:
    下标不是序号,是数据的索引

  • zrevrange 按序号降序获取有序汇合中的内容。

    语法:

    zrevrange key start(索引) stop(索引) [WITHSCORES] 
    

    例:

    zrevrange zset1 0 -1 withscores
    //xiaolong
    //45
    //liubei
    //23
    //libai
    //23
    //xiaolonog
    //12
    
    
  • 按条件获取数据
    zrangebyscore key min max [withscores] [limit]
    zrevrangebyscore key max min [withscores]

    例:
        zrangebyscore scores 50 80 withscores
        //zhangsan 
        //67
        //zhouqi
        //71
  • zrem key member [member] 删除数据
  • 按条件删除数据

    zremrangebyrank 删除汇合中 排名 在指定范畴的元素(程序从小到大排序)

    zremrangebyscore key min max

    语法:

      zremrangebyrank key start stop
    

    第一步:从小到大排序(依据序号)
    第二步:删除元素(依据索引范畴)

      例:删除依据序号从小到大排序后的索引从0到0的元素,也就是删除第一个元素(下标是0的)
          zremrangebyrank zset1 0 0
    
    

  • 汇合交并操作

zinterstore destination mumkeys key [key ……]

zunionstore destination numkeys key [key……]

元素个数

  • zcard key 返回有序汇合中元素的个数
zcard zset1 
//5
  • zcount key min max 指定范畴内汇合中元素的个数

索引(排名)

  • zrank key member
  • zrevrank key member
zadd movies 143 aa 97 bb 201 cc

zrank movies bb
//0

zrevrank movies bb
//2

score值

  • zscore key member 获取给定元素对应的score
zscore movies aa
//143

zscore movies cc
//201
  • zincrby key increment member 批改给定元素对应的score
zincrby movies 1 aa

zscore movies aa
//144

案例:利用 sort set 实现获取最热门的前5帖子信息

思路:

以mysql中的id作为元素,回复量作为序号,
判断元素数量是否大于5个,
大于5个则 通过 zremrangebyrank hot_message 0 0
查的时候查redis,不查mysql

zadd hotmsg 2345 12 
zadd hotmsg 3678 100
zadd hotmsg 23456 89 
zadd hotmsg 1234 13
zadd hotmsg 1234 78

//每减少一个新元素,就删除一个权值最小的旧元素,保留权值最高的5个元素
zadd hotmsg 5678 90


案例:时效性工作治理

例如观影试用VIP、游戏VIP体验、云盘下载体验VIP、数据查看体验VIP。当VIP体验到期后,如何无效治理此类信息。即使对于正式VIP用户也存在对应的治理形式。

网站会定期开启投票、探讨,限时进行,逾期作废。如何无效治理此类过期信息。

解决方案:

  • 对于基于工夫线限定的工作治理,将解决工夫记录为score值,利用排序功能辨别解决的先后顺序
  • 记录下一个要解决的工夫,到期后处理对应工作,移除redis中的记录,并记录下一个要解决的工夫
  • 当新工作退出时,断定并更新以后下一个要解决的工作工夫
  • 为晋升sorted_set的性能,通常将工作依据特色存储成若干个sorted_set。例如1小时内,1天内,周内,月内,季内,年度等,操作时逐级晋升,将行将操作的若干个工作纳入到1小时内解决的队列中
zadd tx 1509802345 uid:1
zadd tx 1509802390 uid:7
zadd tx 1510384284 uid:888

zrange tx 0 -1 withscores
//uid:1
//1509802345
//uid:7
//1509802390
//uid:888
//1510384284

案例:带有权重的工作/音讯队列

当工作或者音讯待处理,造成了工作队列或音讯队列时,对于高优先级的工作要保障对其优先解决,如何实现工作权重治理

解决方案:对于带有权重的工作,优先解决权重高的工作,采纳score记录权重即可

zadd tasks 4 order:id:5
zadd tasks 1 order:id:425
zadd tasks 9 order:id:345


zrevrange tasks 0 0
//order:id:345

zrem tasks order:id:345

多条件工作权重设定

如果权重条件过多时,须要对排序score值进行解决,保障score值可能兼容2条件或者多条件,

例如外贸订单优先于国内订单,总裁订单优先于员工订单,经理订单优先于员工订单

  • 因score长度受限,须要对数据进行阶段解决,尤其是工夫设置为小时或分钟级即可(折算后)
  • 先设定订单类别,后设定订单发动角色类别,整体score长度必须是对立的,有余位补0。第一排序规定首位不得是0

    • 例如外贸101,国内102,经理004,员工008
    • 员工下的外贸单score值为101008
    • 经理下的国内单score值为102004
zadd tt 102004 order:id:1
zadd tt 101008 order:id:2

通用指令

Redis提供了丰盛的命令对数据库和各种数据类型进行操作

1、键值相干的命令
2、服务器相干的命令

key基本操作

  • DEL 该命令用于在 key 存在时删除 key。

    语法:

    del key
    

    例:

    del name
    
  • EXISTS 判断一个 key 是否存在。

    语法:

    exists key
    

    返回值:

    1代表存在(示意存在的数量),0代表不存在
    

    例:

    exists name
    //1
    exists name
    //1
    exists age
    //1
    
  • TYPE 返回 key 所贮存的值的类型。

    语法:

    type key 
    

    例:

    type email 
    //string 
    
    type user:id:2
    //hash 
    
    type user_list
    //list

key时效性管制

1、为指定key设置有效期

  • EXPIRE 为给定 key 设置过期工夫,以秒计。

    语法:

    expire key seconds
    

    例:

    expire user_list 10
    
  • PEXPIRE key milliseconds 设置 key 的过期工夫以毫秒计。
  • EXPIREAT key timestamp

EXPIREAT 的作用和 EXPIRE 相似,都用于为 key 设置过期工夫。
不同在于 EXPIREAT 命令承受的工夫参数是 UNIX 工夫戳(unix timestamp)。

  • PEXPIREAT key milliseconds-timestamp 设置 key 过期工夫的工夫戳(unix timestamp) 以毫秒计

2、获取key的无效工夫

  • TTL 以秒为单位,返回给定 key 的残余生存工夫(TTL, time to live)。

    语法:

    ttl key 
    

    例:

    ttl user_list
    
  • PTTL key 以毫秒为单位返回 key 的残余的过期工夫。

3、切换key从时效性转换为永久性

  • PERSIST key 移除 key 的过期工夫,key 将长久放弃。

key查问

1、keys pattern 返回以后数据库外面的键

* 匹配任意数量的任意符号

? 配合一个任意符号

[] 匹配一个指定符号

例:

keys *  查问所有

keys it* 查问所有以it结尾

keys *heima 查问所有以heima结尾

keys ??heima 查问所有后面两个字符任意,前面以heima结尾

keys user:? 查问所有以user:结尾,最初一个字符任意

keys u[st]er:1 查问所有以u结尾,以er:1结尾,两头蕴含一个字母,s或t

其余key通用操作

  • RENAME key newkey 批改 key 的名称
  • RENAMENX key newkey 仅当 newkey 不存在时,将 key 改名为 newkey
  • sort 对所有key排序
  • DUMP key 序列化给定 key ,并返回被序列化的值。

db操作

  • select

    抉择数据库,在redis外面默认有0-15号数据库,
    默认在0号数据库操作,能够通过redis.conf配置文件进行设置

    语法:

    select 数据库的编号
    

    例:

    select 1
    // ok
    
    keys *
    // empty lisr or set
    
    select 0
    // ok 
    
    keys *
    //email
  • MOVE key db 将以后数据库的 key 挪动到给定的数据库 db 当中。

    例:

    move name 1
    
    
  • flushdb (谨慎应用) 清空以后数据库外面所有的键

    例:

    flushdb
    //ok
    keys *
    //empty list or set
  • flushall (谨慎应用) 清空所有数据库外面的所有的键
  • dbsize 返回以后数据库外面键的个数

    例:

    dbsize
    // 8 
    
  • RANDOMKEY 从以后数据库中随机返回一个 key 。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理