zoukankan      html  css  js  c++  java
  • Redis系列(一)--基础API

    Redis:Remote Dictionary Server

      是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。C语言实现,单线程

    Redis特性:

      1、速度快:官方声明可以达到10W QPS

      2、持久化:aof、rdb

      3、支持多种数据结构:String、Hash Table、LinkedList、Set、Sort Set、BitMaps位图、HyperLogLog超小内存唯一值计数、GEO(地理定位)

      4、支持多种语言:Java、PHP、Python、Ruby、Node.js等

      5、功能丰富:发布订阅、消息队列、Lua脚本自定义命令、事务、pipeLine等

      6、简单:不依赖外部库、单线程模型

     V2.8支持高可用,V3.0支持分布式

    典型使用场景:

     缓存系统、计数器(点赞、转发)、消息队列系统、排行榜、社交网络

    启动方式:

     1、redis-server

     2、动态参数启动

     3、配置文件启动

    API:

    通用命令:

     1、redis-cli -a 123456 -p 6379:-a是指密码验证,-p是指指定端口号

     2、keys *:不要在生产环境使用,数据太多,比较慢,而且Redis是单线程,就会阻塞其他命令,可以使用scan代替,或者从节点扫描

    127.0.0.1:6379> keys *
     1) "set1"
     2) "set2"
     3) "count"
     4) "user:2:info"
     5) "score_rank"
     6) "list1"
     7) "user:1:info"
     8) "user:ranking"
     9) "usercount"
    10) "name"
    11) "ADMIN::LOGIN::COUNT::22"
    12) "set3"
    13) "SMS::CODE::CONTENT::18516714352"
    14) "text"

     支持通配符匹配:

    127.0.0.1:6379> keys n*
    1) "name"
    127.0.0.1:6379> keys nam?
    1) "name"

      3、scan:返回一部分的数据,包含两部分:第一部分是扫描的索引,第二部分是返回的数据

    127.0.0.1:6379> scan 0
    1) "5"
    2)  1) "usercount"
        2) "list1"
        3) "set2"
        4) "count"
        5) "user:2:info"
        6) "user:ranking"
        7) "SMS::CODE::CONTENT::18516714352"
        8) "set1"
        9) "ADMIN::LOGIN::COUNT::22"
       10) "set3"

     4、dbsize:可以在生产环境使用,不是扫描全部数据,Redis本身会记录这个总数,时间复杂度O(1)

    127.0.0.1:6379> dbsize
    (integer) 14

     5、exists:判断是否存在key,1是存在,0是不存在

    127.0.0.1:6379> exists name
    (integer) 1

     6、删除key,存在key,1,不存在key,0

    127.0.0.1:6379> del a
    (integer) 1
    127.0.0.1:6379> del aaaa
    (integer) 0

     7、过期时间设置expire、ttl、persist

    127.0.0.1:6379> expire name 100      //expire,设置100s有效期
    (integer) 1
    127.0.0.1:6379> ttl name          //ttl,剩余过期时间,-1没有过期时间(永久),-2表示key不存在
    (integer) 96
    127.0.0.1:6379> persist name        //persist持久化,去掉过期时间
    (integer) 1
    127.0.0.1:6379> ttl name
    (integer) -1

     8、type key:查看key类型

    127.0.0.1:6379> type set3
    set
    127.0.0.1:6379> type count
    string
    127.0.0.1:6379> type list1
    list
    127.0.0.1:6379> type user:1:info
    hash

     9、object encoding key:查看key对应Redis内部编码,39字符一下为embstr,以上为raw

    Redis对外提供五种数据结构,内部使用编码不同,考虑时间、空间的问题

    127.0.0.1:6379> object encoding name
    "quicklist"
    127.0.0.1:6379> object encoding count
    "int"
    127.0.0.1:6379> object encoding list1
    "quicklist"
    127.0.0.1:6379> object encoding set3
    "hashtable"
    127.0.0.1:6379> object encoding user:1:info
    "ziplist"

    内部编码如下图

     通用命令简单说到这里,有些长命令需要注意,尽量不要在生产环境使用

     长命令:keys/flushall/flushdb/mutil/exec等

    String:

      Redis常用的一种数据机构,普通的key/value存储都可以使用String

    127.0.0.1:6379> set abc def                  //set
    OK
    127.0.0.1:6379> get abc                    //get
    "def"
    127.0.0.1:6379> mset abc1 def1 abc2 def2 abc3 def3    //mset,批量set
    OK
    127.0.0.1:6379> mget abc1 abc2 abc3             //mget,批量get
    1) "def1"
    2) "def2"
    3) "def3"
    127.0.0.1:6379> getset abc ddd                //getset,设置value,返回之前的value
    "def"
    127.0.0.1:6379> get abc
    "ddd"
    127.0.0.1:6379> strlen abc                               //strlen,key的字符串长度
    (integer) 3
    127.0.0.1:6379> append abc e                             //append,字符串拼接,返回拼接后字符串长度
    (integer) 4
    127.0.0.1:6379> get abc                                          
    "ddde"
    127.0.0.1:6379> set abcc aaa                              //set,设置key的value,无论key是否存在,就是saveorupdate操作
    OK
    127.0.0.1:6379> setnx abc    11                           //setnx,设置key的value,key不能是存在的,存在返回0,不存在返回1,即设置成功,就是add操作
    (integer) 0
    127.0.0.1:6379> setnx abccc 1111
    (integer) 1
    127.0.0.1:6379> set abc 11 XX                             //set key value XX,只能设置已存在的key的value,就是update操作
    OK
    127.0.0.1:6379> get abc
    "11"

    自增incr、自减decr、incrby、decrby,String一定要是数字,否则报错

    127.0.0.1:6379> incr count                //incr,+1
    (integer) 3
    127.0.0.1:6379> incrby count 44            //incrby key n,+n
    (integer) 47
    127.0.0.1:6379> decr count                //decr,-1
    (integer) 46
    127.0.0.1:6379> decrby count 12            //decrby key n,-n
    (integer) 34
    127.0.0.1:6379> incr aaaaaa
    (error) ERR value is not an integer or out of range

    注意点:  

      mset和mget是批量操作,时间复杂度O(N)

      n次get:n次网络时间+n次命令时间,主要开销在网络上面,redis get命令执行时间几乎忽略

      1次mget:1次网络时间+n次命令时间

      mset和set:mset具有原子性,可以同一时间将所有key都设置完成

    Hash:

    127.0.0.1:6379> 
    127.0.0.1:6379> hset user:1000001 id 1000001                         //hset, key field value,设置hash key的某个field字段的value
    (integer) 1
    127.0.0.1:6379> hset user:1000001 name jesen                        
    (integer) 1
    127.0.0.1:6379> hset user:1000001 sex 1
    (integer) 1
    127.0.0.1:6379> hsetnx user:1000001 a1 a1                            //hsetnx
    (integer) 1
    127.0.0.1:6379> hget user:1000001 id                                 //hget, key field获取hash key的某个field的value
    "1000001"
    127.0.0.1:6379> hget user:1000001 name
    "jesen"
    127.0.0.1:6379> hset user:1 id 11
    (integer) 1
    127.0.0.1:6379> hdel user:1 id                                        //hdel,删除某个filed
    (integer) 1
    127.0.0.1:6379> hgetall user:1000001                                  //hgetall,获取hash key的所有key和value
    1) "id"
    2) "1000001"
    3) "name"
    4) "jesen"
    5) "sex"
    6) "1"
    127.0.0.1:6379> hkeys user:1000001                                    //hkeys,获取hash key的所有key
    1) "id"
    2) "name"
    3) "sex"
    4) "addr"
    5) "a"
    6) "b"
    7) "c"
    127.0.0.1:6379> hvals user:1000001                                     //hvals,获取hash key的所有value
    1) "1000001"
    2) "jesen"
    3) "1"
    4) "shanghai"
    5) "a"
    6) "b"
    7) "c"
    127.0.0.1:6379> hexists user:1000001 id                                 //hexists,判断key的某个field是否存在,和exists有区别
    (integer) 1
    127.0.0.1:6379> hlen user:1000001                                       //hlen,获取field数量
    (integer) 3
    127.0.0.1:6379> hmget user:1000001 id name sex                          //hmget
    1) "1000001"
    2) "jesen"
    3) "1"
    127.0.0.1:6379> hmset user:1000001 a a b b c c                          //hmset
    OK

    自增:hincrby、hincrbyfloat,hash没有hdecr和hdecrby,hincrbyfloat增加的float型,可以负值,就可以实现自减

    127.0.0.1:6379> hincrby user:1000001 login_times 2
    (integer) 2
    127.0.0.1:6379> hincrbyfloat user:1000001 login_times 1.1
    "3.1"
    127.0.0.1:6379> hincrby user:1000001 login_times -1
    (error) ERR hash value is not an integer
    127.0.0.1:6379> hincrbyfloat user:1000001 login_times -1
    "2.1"

    注意点:

      1、hgetall、hkeys、hvals,时间复杂度O(N)

      2、hmset、hmget是对一个key的多个field进行操作

    应用场景:

      1、例如存储用户对象数据,包括ID、姓名、性别等,通过ID获取对应字段

      2、实现记录登录次数类似功能

    List:

    127.0.0.1:6379> rpush userlist 1 2 3 4 5            //rpush,从右边逐个添加,list里面就是 1 2 3 4 5
    (integer) 5
    127.0.0.1:6379> rpop userlist                        //rpop,从右边删除一个元素,list里面就是1 2 3 4
    "5"
    127.0.0.1:6379> lpush userlist a b c d f            //lpush,从左边逐个添加,list里面就是f d c b a 1 2 3 4
    (integer) 9
    127.0.0.1:6379> lpop userlist                        //lpop,从左边删除一个元素,list里面就是d c b a 1 2 3 4
    "f"
    127.0.0.1:6379> linsert userlist before 1 haha        //linsert,在1的前面添加元素haha,list里面就是d c b a haha 1 2 3 4
    (integer) 9
    127.0.0.1:6379> linsert userlist after a hehe        //linsert,在a的后面添加元素hehe,list里面就是d c b a hehe haha 1 2 3 4
    (integer) 10
    127.0.0.1:6379> lrange userlist 0 20          //lrange key start end,索引从左到右:0~N,从右到左:-1~-(N+1)
     1) "d"
     2) "c"
     3) "b"
     4) "a"
     5) "hehe"
     6) "haha"
     7) "1"
     8) "2"
     9) "3"
    10) "4"
    127.0.0.1:6379> lrem userlist 3 1            //lrem key count value, 如果count>0,从右到左删除count个和value相同的值,count<0,从左到右删除,count=0,和value相同的值全部删除
    (integer) 1
    127.0.0.1:6379> ltrim userlist 0 3            //ltrim key start end,截取start到end的value,首位为0
    OK
    127.0.0.1:6379> lindex userlist 0            //lindex key index,查询index位置的value,首位0,末位-1
    "d"
    127.0.0.1:6379> lindex userlist -1
    "a"
    127.0.0.1:6379> llen userlist                //llen ,list的长度
    (integer) 4
    127.0.0.1:6379> lset userlist 0 eee            //lset key index value,只是update,不能超过list下标最大值
    OK

     还有很重要的几个API:

    127.0.0.1:6379> lpush list 1
    (integer) 1
    127.0.0.1:6379> blpop list 10                    //blpop,从左边弹出一个元素,在timeout时间内如果没有元素就阻塞
    1) "list"
    2) "1"
    (4.98s)
    127.0.0.1:6379> brpop list 10                    //brpop,从右边谈,和blpop相同
    1) "list"
    2) "1"
    (4.98s)
    127.0.0.1:6379> rpoplpush userlist list            //rpoplpush source destination,从source的右边弹出,push到destination的左边
    "a"
    127.0.0.1:6379> brpoplpush list userlist 20        //brpoplpush source destination timeout,timeout时间内弹出,会阻塞
    "b"
    (9.52s)

    blpop和rpush、lpush和brpop可以用来实现消息队列

    应用场景:

       社交软件的关注列表、粉丝列表等都是用list实现

    Set:

    127.0.0.1:6379> sadd userset mazi                    //sadd key member... ,可以添加多个元素
    (integer) 1
    127.0.0.1:6379> scard userset                        //scard,set的member个数
    (integer) 4
    127.0.0.1:6379> sismember userset zhangsan           //sismember key member,判断元素是否存在
    (integer) 1
    127.0.0.1:6379> srandmember userset 2                //srandmember key n,随机getn个元素
    1) "zhangsan"
    2) "mazi"
    127.0.0.1:6379> smembers userset                     //smembers,get set所有元素
    1) "lisi"
    2) "zhangsan"
    3) "wanger"
    4) "mazi"
    127.0.0.1:6379> srem userset lisi                    //srem,删除元素
    (integer) 1
    127.0.0.1:6379> sdiff userset stuset                 //sdiff set1 set2,得到set1相对于set2的差集
    1) "wanger"
    2) "mazi"
    127.0.0.1:6379> sdiff stuset userset                 //sdiff set2 set1,得到set2相对于set1的差集
    1) "lisi"
    2) "sb"
    127.0.0.1:6379> sinter userset stuset                 //sinter,set之间的交集
    1) "zhangsan"
    127.0.0.1:6379> sunion userset stuset                 //sunion,set之间的合集
    1) "wanger"
    2) "mazi"
    3) "zhangsan"
    4) "lisi"
    5) "sb"

    sdiff、sinter、sunion后面的set之间用空格,而不是逗号

    应用场景:

      set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据

    时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的

    ZSet:有序集合

    127.0.0.1:6379> zadd user:rank 1 faker 2 thshy 5 rookie 3 ning 12 uzi 8 clearlove 100 doublelift        //zadd [NX|XX]
    (integer) 7
    127.0.0.1:6379> zadd user:rank XX 2 theshy
    (integer) 0
    127.0.0.1:6379> zadd user:rank NX 2 theshy
    (integer) 1
    127.0.0.1:6379> zrem user:rank dog                                     //zrem
    (integer) 1
    127.0.0.1:6379> zscore user:rank theshy                                //zsore,根据member得到score
    "2"
    127.0.0.1:6379> zincrby user:rank 999 uzi                              //zincrby,给指定member增加score
    "1087"
    127.0.0.1:6379> zcard user:rank                                        //zcard,zset长度
    (integer) 8
    127.0.0.1:6379> zrank user:rank uzi                                    //zrank,member排名
    (integer) 7
    127.0.0.1:6379> zrange user:rank 0 10 withscores                      //zrange,得到指定范围的元素 withscores将对应score也展示出来
     1) "faker"
     2) "1"
     3) "theshy"
     4) "2"
     5) "thshy"
     6) "2"
     7) "ning"
     8) "3"
     9) "rookie"
    10) "5"
    11) "clearlove"
    12) "8"
    13) "doublelift"
    14) "100"
    15) "uzi"
    16) "1087"
    127.0.0.1:6379> zrangebyscore user:rank 5 100                         //zrangebyscore,指定score范围内的元素
    1) "rookie"
    2) "clearlove"
    3) "doublelift"
    127.0.0.1:6379> zcount user:rank 5 10                                 //zcount指定score范围内的元素计数count
    (integer) 2
    127.0.0.1:6379> zremrangebyrank user:rank 101 1100                     //zremrangebyrank,zset中删除指定排名范围内的元素,不是score范围内,容易误解
    (integer) 0
    127.0.0.1:6379> zremrangebyrank user:rank 7 8
    (integer) 1

    应用场景:

      sorted set的使用场景与set类似,区别是set不是自动有序的,而sorted set可以通过用户额外提供一个优先级(score)的参数来为成员排序,

    并且是插入自动排序。当你需要一个有序的并且不重复的集合列表,那么可以选择sorted set数据结构,比如twitter 的public timeline可以以

    发表时间作为score来存储,这样获取时就是自动按时间排好序的。

  • 相关阅读:
    自学人工智能之数学篇,数学入门并不难
    2018-8-10-win10-uwp-使用资源在后台创建控件
    2019-9-2-win10-uwp-弹起键盘不隐藏界面元素
    2019-7-31-程序猿修养-日志应该如何写
    2018-11-19-WPF-在image控件用鼠标拖拽出矩形
    2019-8-31-C#-如何给-ValueTuple-返回值添加注释
    2019-11-12-浅谈-Windows-桌面端触摸架构演进
    2018-8-10-win10-uwp-打开文件管理器选择文件
    2018-8-10-win10-uwp-验证输入-自定义用户控件
    2019-8-31-dotnet-特性-DynamicallyInvokable-是用来做什么的
  • 原文地址:https://www.cnblogs.com/huigelaile/p/10877091.html
Copyright © 2011-2022 走看看