Redis的API应用

全局命令

   1,查看所有键:keys *   set school dongnao   set hello world

   2,键总数 dbsize  //2个键,如果存在大量键,线上禁止使用此指令

   3,检查键是否存在:exists key  //存在返回1,不存在返回0

   4,删除键:del key  //del hello school, 返回删除键个数,删除不存在键返回0

   5,键过期:expire key seconds  //set name test  expire name 10 //10秒过期

                     ttl 查看剩余的过期时间

   6,键的数据结构类型:type key //type hello  //返回string,键不存在返回none

   7,flushall 清空所有数据 flushdb 清空当前库数据,redis单机环境下有16个库(0-15)

单线程架构

 列举例子:三个客户端同时执行命令

         客户端1:set name test

         客户端2:incr num

         客户端3:incr num

执行过程:发送指令-〉执行命令-〉返回结果

执行命令:单线程执行,所有命令进入队列,按顺序执行,使用I/O多路复用解决I/O问题,后面有介绍(由于读写操作等待用户输入或输出都是阻塞的,所以 I/O 操作在一般情况下往往不能直接返回,这会导致某一文件的 I/O 阻塞导致整个进程无法对其它客户提供服务 ,IO多路复用模型是建立在内核提供的多路分离函数select基础之上的,使用select函数可以避免同步非阻塞IO模型中轮询等待的问题)

单线程快原因:纯内存访问, 非阻塞I/O(使用多路复用),单线程避免线程切换和竞争产生资源消耗

问题:如果某个命令执行,会造成其它命令的阻塞

字符串<String>

1,字符串类型:

实际上可以是字符串(包括XML JSON),还有数字(整形 浮点数),二进制(图片 音频 视频),最大不能超过512MB

2,设值命令:

set age 23 ex 10 //10秒后过期  px 10000 毫秒过期

setnx name test  //不存在键name时,返回1设置成功;存在的话失败0

set age 25 xx    //存在键age时,返回1成功

场景:如果有多客户同时执行setnx,只有一个能设置成功,可做分布式锁

3.获值命令:

get age //存在则返回value, 不存在返回nil

4.批量设值:

mset country china city beijing

5.批量获取:

mget country city address //返回china  beigjin, address为nil

若没有mget命令,则要执行n次get命令

01f75022d0d2908e773f26f0d24822550da.jpg

使用mget=1次网络请求+redis内部n次查询

a0bdfb56917d6be487de73a103167b5b3c2.jpg

6.计数:

incr age //必须为整数自加1,非整数返回错误,无age键从0自增返回1

decr age //整数age减1

incrby age 2 //整数age+2

decrby age 2//整数age -2

incrbyfloat score 1.1 //浮点型score+1.1

7.append追加指令:

set name hello; append name world //追加后成helloworld

8.字符串长度:

set hello “世界”;strlen hello//结果6,每个中文占3个字节

9.截取字符串:

set name helloworld ; getrange name 2 4//返回 llo

10.内部编码:

int:            8字节长整理//set age 100; object encoding age //返回int

embstr:    小于等于39字节串set name bejin; object encodeing name//embstr

raw:          大于39字节的字符串set a fsdfwerwerweffffffffffdfs//返回raw

 

Ps: 

   Flushall清除所有数据  flushdb  清库

   redis 单点环境下有16个库   select 15 可以切换到第15个数据库 集群只有一个数据库0

应用场景

1.键值设计: 

业务名:对象名:id:[属性],数据库为order, 用户表user,对应的键可为 order:user:1 或order:user:1:name

注意:

redis目前处于受保护模式,不允许非本地客户端链接,可以通过给redis设置密码,然后客户端链接的时候,写上密码就可以了

127.0.0.1:6379> config set requirepass 123456  临时生效

或者修改redis.conf   requirepass 123456,启动时./redis-server redis.conf指定conf

./redis-cli -p 6379 -a 12345678  //需要加入密码才能访问

切换数据库:

 select 2

 

场景实践cache-demo

JedisAllCommandTest OrderListHashTest SiteVisitNumTest

 

操作工具

redis通用工具类

public class JedisUtils {

	private JedisPool pool = null;

	//具体使用见java代码
}

jedis缓存工具类,使用redisTemlate处理

@Component
public class RedisUtil {

	// spring 对redis操作的封装,使用了模板模式
	@Resource
	private RedisTemplate<String, Object> template;

}

Spring的配置

	<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
		<property name="maxTotal" value="100" />
		<property name="maxIdle" value="10" />
	</bean>

	<bean id="jedisConnectionFactory"
		class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
		destroy-method="destroy">
		<property name="hostName" value="192.168.1.111" />
		<property name="port" value="6379" />
		<property name="database" value="2" />
		<property name="timeout" value="3000" />
		<property name="usePool" value="true" />
		<property name="password" value="12345678"/>
		<property name="poolConfig" ref="jedisPoolConfig" />
	</bean>

	<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
		<property name="connectionFactory" ref="jedisConnectionFactory" />
		<property name="keySerializer" ref="stringRedisSerializer"/>
			 
		<property name="valueSerializer" ref="stringRedisSerializer"/>
		
		<property name="enableTransactionSupport" value="false"></property>
	</bean>
	
	
	
	<bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" />  
    <bean  id ="JdkSerializationRedisSerializer" class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>  
  
    <bean  id="GenericToStringSerializer" class="org.springframework.data.redis.serializer.GenericToStringSerializer"  
            c:type="java.lang.Long"/>  
	
	
    <cache:annotation-driven/>

	<!-- declare Redis Cache Manager -->
	<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">
		<constructor-arg index="0" ref="redisTemplate"></constructor-arg>
	</bean>

 

哈希hash

是一个string类型的field和value的映射表,hash特适合用于存储对象。

ea738eec3a0dc1db96608c24b5a58f84a16.jpg

命令  hset key field value

设值:hset user:1 name james         //成功返回1,失败返回0

取值:hget user:1 name              //返回james

删值:hdel user:1 age               //返回删除的个数

计算个数:hset user:1 name james; hset user:1 age 23;

                hlen user:1               //返回2,user:1有两个属性值

批量设值:hmset user:2 name james age 23 sex boy //返回OK

批量取值:hmget user:2 name age sex   //返回三行:james 23 boy

判断field是否存在:hexists user:2 name //若存在返回1,不存在返回0

获取所有field: hkeys user:2            // 返回name age sex三个field

获取user:2所有value:hvals user:2     // 返回james 23 boy

获取user:2所有field与value:hgetall user:2 //name age sex james 23 boy值

增加1:hincrby user:2 age 1      //age+1

            hincrbyfloat user:2 age 2   //浮点型加2

内部编码

      ziplist<压缩列表>和hashtable<哈希表>

      当field个数少且没有大的value时,内部编码为ziplist

      如:hmset user:3 name james age 24; object encoding user:3 //返回ziplist

      当value大于64字节,内部编码由ziplist变成hashtable

      如:hset user:4 address “fsgst64字节”; object encoding user:3 //返回hashtable

应用场景

    比如将关系型数据表转成redis存储:

b80e10a16e3eb9a8151ae602f9f16e91597.jpg

e9f64608cdba8fadfcd0726a910262b0a4f.jpg

HASH类型是稀疏,每个键可以有不同的filed, 若用redis模拟做关系复杂查询开发因难,维护成本高

三种方案实现用户信息存储优缺点

1.原生:

            set user:1:name james;

             set user:1:age  23;

             set user:1:sex boy;

      优点:简单直观,每个键对应一个值

      缺点:键数过多,占用内存多,用户信息过于分散,不用于生产环境

2.将对象序列化存入redis

            set user:1 serialize(userInfo);

      优点:编程简单,若使用序列化合理内存使用率高

      缺点:序列化与反序列化有一定开销,更新属性时需要把userInfo全取出来进行反序列化,更新后再序列化到redis

3.使用hash类型

             hmset user:1 name james age 23 sex boy

       优点:简单直观,使用合理可减少内存空间消耗

       缺点:要控制ziplist与hashtable两种编码转换,且hashtable会消耗更多内存

总结:对于更新不多的情况下,可以使用序列化,对于VALUE值不大于64字节可以使用hash类型

 

列表 list

用来存储多个有序的字符串,一个列表最多可存2的32次方减1个元素

285291da75eaacc9c289486c500213315d3.jpg

因为有序,可以通过索引下标获取元素或某个范围内元素列表,列表元素可以重复

列表命令

063ce65f4b7b8c1ad70e9df2c62064ff66b.jpg

添加命令

rpush james c b a //从右向左插入cba, 返回值3

lrange james 0 -1 //从左到右获取列表所有元素 返回 c b a

lpush key c b a //从左向右插入cba

linsert james before b teacher //在b之前插入teacher, after为之后,使用lrange james 0 -1 查看:c teacher b a

查找命令

lrange key start end //索引下标特点:从左到右为0到N-1

lindex james -1 //返回最右末尾a,-2返回b

llen james    //返回当前列表长度

lpop james   //把最左边的第一个元素c删除

rpop james   //把最右边的元素a删除
 
lrem key count value//删除指定元素

应用场景设计: cacheListHashApplicationTest用例

 每个用户有多个订单key为 order:1   order:2  order:3, 结合hmset

hmset order:1 orderId 1 money 36.6 time 2018-01-01

hmset order:2 orderId 2 money 38.6 time 2018-01-01

hmset order:3 orderId 3 money 39.6 time 2018-01-01

把订单信息的key放到队列

     lpush user:1:order order:1 order:2 order:3

每新产生一个订单,

     hmset order:4 orderId 4 money 40.6 time 2018-01-01

追加一个order:4放入队列第一个位置

    lpush user:1:order order:4

当需要查询用户订单记录时:

    List orderKeys = lrange user:1 0 -1 //查询user:1 的所有订单key值

   for(Order order: orderKeys){

           hmget order:1

    }

列表内部编码:

1,当元素个数少且没大元素,编码为ziplist,减少内存的使用

   rpush list a b c

   object encoding list //返回ziplist

2,当元素超过512个,或元素超过64字节,内部编码变成linkedlist链表;

   rpush list a1 a2 ....a513  或rpush list xxxxxxxxxxxxxx

   object encoding list  //linkedlist

 

集合<SET> 用户标签,社交,查询有共同兴趣爱好的人,智能推荐

保存多元素,与列表不一样的是不允许有重复元素,且集合是无序,一个集合最多可存2的32次方减1个元素,除了支持增删改查,还支持集合交集、并集、差集;

c7fdf0f777f4ff50e95a521d493bb631ca0.jpg

命令:

 exists user    //检查user键值是否存在

 sadd user a b c     //向user插入3个元素,返回3

 sadd user a b     //若再加入相同的元素,则重复无效,返回0

 smember user //获取user的所有元素,返回结果无序

 srem user a   //返回1,删除a元素

 scard user    //返回2,计算元素个数

 sismember user a //判断元素是否在集合存在,存在返回1,不存在0

 srandmember user 2 //随机返回2个元素,2为元素个数

 spop user 2        //随机返回2个元素a b,并将a b从集合中删除

 smember user   //此时已没有a b, 只有c

 

集合的交集:

  sadd user:1 zhangsan 24 girl

  sadd user:2 james 24 boy      //初始化两个集合

  sinter user:1 user:2     //求两集合交集, 此时返回24

 

  sadd user:3 wang 24 girl     //新增第三个元素

  sinter user:1 user:2 user:3    //求三个集合的交集,此时返回24

 

集合的并集(集合合并去重):

  sunion user:1 user:2 user:3   //三集合合并(并集),去重24

  sdiff user:1 user:2          //1和2差集,(zhangsan 24 girl)-(james 24 boy)=zhangsan girl

 

将交集(jj)、并集(bj)、差集(cj)的结果保存:

  sinterstore user_jj user:1 user:2     //将user:1 user:2的交集保存到user_jj

  sunionstore user_bj user:1 user:2 //将user:1 user:2的(并)合集保存user_bj

  sdiffstore user_cj user:1 user:2     //将user:1-user:2的差集保存user_cj

  smemebers user_cj       // 返回zhangsan girl

内部编码:

      sadd user 1 2 3 4      //当元素个数少(小于512个)且都为整数,redis使用intset减少内存的使用

      sadd user 1 2...513   //当超过512个或不为整数(比如a b)时,编码为hashtable

      object encoding user //hashtables

使用场景:

  标签,社交,查询有共同兴趣爱好的人,智能推荐

  使用方式:给用户添加标签:

  sadd user:1:fav basball fball pq

  sadd user:2:fav basball fball   

  ............

  或给标签添加用户

  sadd basball:users user:1 user:3

  sadd fball:users user:1 user:2 user:3

  ........

  计算出共同感兴趣的人:

   sinter user:1:fav user2:fav

   规则

   sadd (常用于标签)  spop/srandmember(随机,比如抽奖)

   sadd+sinter (用于社交,查询共同爱好的人,匹配)

 

有序集合: 常用于排行榜,如视频网站需要对用户上传视频做排行榜,或点赞数

与集合有联系,不能有重复的成员

012a7c086bcb99fc5f7cb3aa0e50c3db29d.jpg

与LIST SET 对比

527e827bd846384ecd33824a43f28e3377c.jpg

命令

   zadd key score member [score member......]

   zadd user:zan 200 james     //james的点赞数1, 返回操作成功的条数1

   zadd user:zan 200 james 120 mike 100 lee    // 返回3

   zadd test:1 nx 100 james               //键test:1必须不存在,主用于添加

   zadd test:1 xx incr 200 james       //键test:1必须存在,主用于修改,此时为300

   zadd test:1 xx ch incr -299 james //返回操作结果1,300-299=1

   zrange test:1 0 -1 withscores  //查看点赞(分数)与成员名

   zcard test:1     //计算成员个数, 返回1

查点赞数

   zadd test:2 nx 100 james //新增一个集合

   zscore test:2 james     //查看james的点赞数(分数),返回100

排名:

   zadd user:3 200 james 120 mike 100 lee    //先插入数据

   zrange user:3 0 -1 withscores         //查看分数与成员

lee

mike

james

100

120

200

    zrank user:3 james  //返回名次:第3名返回2,从0开始到2,共3名

    zrevrank user:3 james //返回0, 反排序,点赞数越高,排名越前

删除成员:

    zrem user:3 jame mike //返回成功删除2个成员,还剩lee

增加分数:

    zincrby user:3 10 lee     //成员lee的分数加10

    zadd user:3 xx incr 10 lee //和上面效果一样

返回指定排名范围的分数与成员

    zadd user:4 200 james 120 mike 100 lee    //先插入数据

    zrange user:4 0 -1 withscores     //返回结果如下图

e8c8667ac01838f61c1c99f30c10ff1da23.jpg

    zrevrange user:4 0 -1 withscores   //倒序,结果如下图

dd3d27c7204eb2d953ec99585033c556b63.jpg

返回指定分数范围的成员

    zrangebyscore user:4 110 300 withscores    //返回120 lee ,200 James, 由低到高

    zrevrangebyscore user:4 300 110 withscores     //返回200james 120lee,由高到低

    zrangebyscore user:4 (110 +inf withscores        //110到无限大,120mike 200james

    zrevrangebyscore user:4 (110 -inf withscores    //无限小到110,返回100 lee

返回指定分数范围的成员个数:

    zcount user:4 110 300  //返回2,由mike120和james200两条数据

删除指定排名内的升序元素:

    zremrangebyrank user:4 0 1 //分数升序排列,删除第0个与第1个,只剩james

删除指定分数范围的成员

    zadd user:5 200 james 120 mike 100 lee    //先插入测试数据

    zremrangebyscore user:5 100 300             //删除分数在100与300范围的成员

    zremrangebyscore user:5 (100 +inf        //删除分数大于100(不包括100),还剩lee

 

有序集合交集:

   格式:zinterstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

         destination:交集产生新的元素存储键名称

         numkeys:  要做交集计算的键个数

         key :元素键值

         weights:每个被选中的键对应值乘weight, 默认为1

  初始化数据:

       zadd user:7 1 james 2 mike 4 jack 5 kate      //初始化user:7数据

       zadd user:8 3 james 4 mike 4 lucy 2 lee  6 jim  //初始化user:8数据

  交集例子:

      zinterstore user_jj 2 user:7 user:8 aggregate sum

        //2代表键合并个数,aggregate sum可加也不可加上,因为默认是sum结果user_jj:4james(1+3), 6mike(2+4)

      zinterstore user_jjmax 2 user:7 user:8 aggregate max 或min

        //取交集最大的分数,返回结果 3james  4mike, min取最小

  weights:

      zinterstore user_jjweight 2 user:7 user:8 weights 8 4 aggregate max

      //1,取两个成员相同的交集,user:7->1 james  2 mike;  user:8->3 james  4 mike

      //2,将user:7->james 1*8=8,  user:7->mike 2*8 =16, 最后user:7结果 8 james  16 mike;

      //3,将user:8-> james 3*4=12, user:8->mike 4*4=16 最后user:8结果12 james  16 mike

      //4,最终相乘后的结果,取最大值为  12 james 16mike

      //5, zrange user_jjweight 0 -1 withscores 查询结果为  12 james 16mike

    总结:将user:7成员值乘8,将user:8成员值乘4,取交集,取最大

 

有序集合并集(合并去重):

格式:zunionstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

         destination:交集产生新的元素存储键名称

         numkeys:  要做交集计算的键个数

         key :元素键值

         weights:每个被选中的键对应值乘weight, 默认为1

zunionstore user_jjweight2 2 user:7 user:8 weights 8 4 aggregate max

//与以上zinterstore一样,只是取并集,指令一样

有序集合内部编码

  1. ziplist:  zadd user:9 20 james 30 mike 40 lee

                    object encoding user:init

                    //当元素个数少(小于128个),元素值小于64字节时,使用ziplist编码,可有效减少内存的使用

    2,skiplist:  zadd user:10 20 james......

                    //大于128个元素或元素值大于64字节时为skiplist编码

使用场景

   排行榜系统,如视频网站需要对用户上传的视频做排行榜

   点赞数:zadd user:1:20180106 3 mike  //mike获得3个赞

   再获一赞:zincrby user:1:20180106 1 mike  //在3的基础上加1

   用户作弊,将用户从排行榜删掉:zrem user:1:20180106 mike

   展示赞数最多的5个用户:zrevrangebyrank user:1:20180106  0  4

   查看用户赞数与排名: zscore user:1:20180106 mike   zrank user:1:20180106 mike

PS:如何将Mysql表数据导入redis?

 

 

 

 

转载于:https://my.oschina.net/u/3728166/blog/2248189

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值