Redis入门详解及redis的常用基本数据结构

1.redis是什么:

Redis是一个非常流行的基于内存的轻量级键值数据库,Redis是一个高性能的kv对(键值)缓存和内存NoSql数据库

2.redis的应用场景

1) 用来做缓存--redis的所有的数据都是放在内存中(内存数据库)

2) 可以用于实现简单的队列系统

3) 在离线批处理数据中,可以作为外部字典的知识库,来实现分布式计算过程中的外部数据查询

可以在某些特定应用场景下替代传统数据库解决一些特定需求

——比如社交类的应用(共同好友,使用了某项功能的人数统计)

——session共享、购物车

3. redis的特点

  1. Redis数据访问速度快(数据在内存中,并有优化的存储结构设计)
  2. Redis相比其他缓存工具(ehcach/memcached),有一个鲜明的优势:支持丰富的数据结构
  3. Redis有数据持久化机制,持久化机制有两种:

            定期将内存数据dump到磁盘;(耗费运行时性能,但是宕机后的恢复过程快)

            AOF(append only file)持久化机制——用记日志的方式记录每一次更新操作,一旦出现灾难事件,可以通过日志重放来恢复整个数据库(耗费运行时性能小,但是宕机后的恢复过程慢)

     4.  Redis支持集群模式(容量可以线性扩展)

4. redis 的数据结构类型

4.1 String类型的数据

1) 插入和读取一条string 类型的数据

set key1 value1

get key1 

2) 对string 类型的数据进行增减(前提是这条数据的value可以看成是数字)

DECRBY key decrement :对 value减去一个自己指定的数字

INCRBY key increment:对value 增加一个自己指定的数字

3) 一次性插入多条数据和一次性获取多条数字

MSET  key1  value1   key2  value2  …..

MGET  key1  key2

4) 对插入的string 类型的数据可以指定一个存活期

 setex key1 10 zss   这条数据在10秒之后就会被自动的删除

4.2 用java客户端插入对象到redis中

 /**
     * 测试将对象序列化之后写入到redis中
     *
     * @throws IOException
     */
    @Test
    public void testObjectPerson() throws IOException {
        Jedis jedis = new Jedis("linux01", 6379);
        Person p1 = new Person("zss", 18, "男");
        Person p2 = new Person("lss", 28, "女");
        Person p3 = new Person("ww", 38, "女");
        Person p4 = new Person("hh", 48, "男");
        //将对象放入集合中方便一次性写入到redis 中
        ArrayList<Person> list = new ArrayList<Person>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        list.add(p4);
        //将对象序列化成字节数组
        ByteArrayOutputStream ba = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(ba);
        //用对象序列化流来将p对象序列化,然后把序列化之后的二进制数据写到ba流中
        oos.writeObject(p4);
        //将ba流转成byte数组
        byte[] pBytes = ba.toByteArray();
        //将对象序列化之后的byte数组存到redis的string结构数据中
        jedis.set("list1".getBytes(), pBytes);
        jedis.close();
    }

    /**
     * 将序列化写入到redis中的对象反序列化读取出来
     *
     * @throws Exception
     */
    @Test
    public void deObjectPerson() throws Exception {
        //将redis 中的对象通过反序列化读取出来
        Jedis jedis = new Jedis("linux01", 6379);
        //根据key从redis中读入出数据
        byte[] bytes = jedis.get("list".getBytes());
        //将bytes反序列化出来
        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bais);
        //从对象读取流中读取出数据
        Object o = ois.readObject();
        System.out.println(o);
        jedis.close();
    }

5. redis 中的list数据类型

从头部(左边)插入数据

redis>LPUSH  key  value1  value2  value3   

从尾部(右边)插入数据

redis>RPUSH  key  value1  value2  value3  

读取list中指定范围的values

redis>LRANGE  key  start   end

redis> lrange  task-queue  0  -1      读取整个list

从头部弹出一个元素

LPOP  key

从尾部弹出一个元素

RPOP  key

从一个list的尾部弹出一个元素插入到另一个list

RPOPLPUSH   key1    key2     ## 这是一个原子性操作

6.redis中的hash数据类型

6.1 往redis库中插入一条hash类型的数据

redis> HSET  key  field  value

redis 127.0.0.1:6379> hset user001:zhangsan  iphone  6

redis 127.0.0.1:6379> hset user001:zhangsan   xiaomi 7

redis 127.0.0.1:6379> hset user001:zhangsan   meizu 8

插入redis中的结果展示:

6.2  取出一条hash类型数据中所有field-value对

redis 127.0.0.1:6379> hgetall user001:zhangsan

1) "iphone"

2) "6"

3) "xiaomi"

4) "7"

5) "meizu"

6) "8"

6.3 取出hash数据中所有fields

redis 127.0.0.1:6379> HKEYS user001:zhangsan

1) "iphone"

2) "xiaomi"

3) "meizu"

6.4 取出hash数据中所有的value

redis 127.0.0.1:6379> hvals user001:zhangsan

1) "6"

2) "7"

3) "8"

6.5 取出hash数据中一个指定field的值

redis 127.0.0.1:6379> hget user001:zhangsan xiaomi

"8"

6.6 为hash数据中指定的一个field的值进行增减

redis 127.0.0.1:6379> HINCRBY user001:zhangsan xiaomi 1

6.7 从hash数据中删除一个字段field及其值

redis 127.0.0.1:6379> HDEL user001:zhangsan iphone

7. Set数据结构功能

set数据类型的特点:无序,无重复元素

7.1 插入一条set数据

redis 127.0.0.1:6379> sadd frieds:zhangsan  bingbing baby fengjie furong ruhua tingting

(integer) 6

redis 127.0.0.1:6379> scard frieds:zhangsan 求总人数

(integer) 6

7.2 获取一条set数据的所有members

redis 127.0.0.1:6379> smembers frieds:zhangsan

7.3 判断一个成员是否属于某条指定的set数据 是返回1 不是返回0

redis 127.0.0.1:6379> sismember frieds:zhangsan liuyifei     #如果不是,则返回0

(integer) 0

redis 127.0.0.1:6379> sismember frieds:zhangsan baby       #如果是,则返回1

(integer) 1

7.4 求两个set数据的差集(集合A有的元素而集合B中没有的元素)

1. redis 127.0.0.1:6379> sdiff  frieds:zhangsan  friends:xiaotao

1) "furong"

2) "fengjie"

3) "ruhua"

4) "feifei"

2.  求差集,并将结果存入到另一个set

redis 127.0.0.1:6379> sdiffstore zhangsan-xiaotao frieds:zhangsan friends:xiaotao

(integer) 4

7.5 求交集,求并集

#求交集

redis 127.0.0.1:6379> sinterstore zhangsan:xiaotao frieds:zhangsan friends:xiaotao

(integer) 2

redis 127.0.0.1:6379> smembers zhangsan:xiaotao

1) "bingbing"

2) "baby"

#求并集

redis 127.0.0.1:6379> sunion  frieds:zhangsan friends:xiaotao

 1) "fengjie"

 2) "tangwei"

 3) "liuyifei"

 4) "bingbing"

 5) "ruhua"

 6) "feifei"

 7) "baby"

 8) "songhuiqiao"

 9) "furong"

10) "yangmi"

8. SortedSet(有序set集合)数据结构

SortedSet 结构的简述: sortedset中存储的成员都有一个附带的分数值,而redis就可以根据分数来对成员进行各种排序(正序、倒序)

8.1 往redis库中插入一条sortedset数据

redis 127.0.0.1:6379> zadd nansheng:yanzhi:bang  70 liudehua  90 huangbo  100 weixiaobao  250 yangwei  59 xiaotao

(integer) 5

8.2  从redis 中查询SortedSet 结果

#正序结果

redis 127.0.0.1:6379> zrange nanshen:yanzhi:bang  0  4

1) "xiaotao"

2) "liudehua"

3) "huangbo"

4) "weixiaobao"

5) "yangwei"

#倒序结果

redis 127.0.0.1:6379> zrevrange nanshen:yanzhi:bang 0 4

1) "yangwei"

2) "weixiaobao"

3) "huangbo"

4) "liudehua"

5) "xiaotao"

8.3 查询某个成员的名次

#在正序榜中的名次

redis 127.0.0.1:6379> zrank nanshen:yanzhi:bang  xiaotao

(integer) 0

#在倒序榜中的名次

redis 127.0.0.1:6379> zrevrank nanshen:yanzhi:bang xiaotao

(integer) 4

8.4 修改成员的分数

redis 127.0.0.1:6379> zincrby nanshen:yanzhi:bang  300  xiaotao

"359"

redis 127.0.0.1:6379> zrevrank nanshen:yanzhi:bang xiaotao

(integer) 0

9. GEO数据结构

geo数据结构的特点:GEO数据类型支持便捷的geo地理位置计算

1. 添加地点及gps坐标:

doitedu03:6379> GEOADD CN:DIS 121.896321 46.8723843 JS:NT:TN 121.896533 46.872622 JS:NT:NN

(integer) 2

2. 获取指定地点的gps坐标

doitedu03:6379> GEOPOS CN:DIS JS:NT:NN

1) "121.89653187990188599"

2) "46.87262258451151808"

3. 查询指定地点指定半径内的相邻点

linux01:6379> GEORADIUS CN:DIS 121.896341 46.8723853 1 km

1) "JS:NT:TN"

2) "JS:NT:NN"

linux01:6379>

10 BitMap数据结构

10.1 Bitmap基本使用

位图(也称为位数组或位向量)是由比特位(bit)组成的数组。Redis 中的位图并不是一种新的数据类型,它实际的底层数据类型是字符串。因为字符串本质上是二进制大对象(BLOB,BinaryLarge OBject ),所以可以将其视做位图。同时,因为位图存储的是布尔信息,所以在某些情况下可以节省大量的内存空间。

11 HyperLogLog数据结构

11.1 HyperLogLog算法介绍:

在Redis 中,如果我们不需要获取数据集的内容,而只是想得到不同值的个数,那么就可以使用HyperLogLog( HLL)数据类型来优化使用集合类型时存在的内存和性能问题。Reids中 HLL的优势在于能够使用固定数量的内存(每个HyperLogLog 类型的键只占用12KB内存,却最多可以计算264个不同元素的基数)和常数时间复杂度O(1)不过,由于HLL算法返回的基数(译者注:HLL和常数时间复杂度(每个键O(1))进行唯一计数。不过,由于HLL算法返回的基数可能不准确(标准差小于1%),因此在决定是否使用HLL时需要进行权衡。

11.2 HyperLogLog的核心思想

利用一个元素的hashcode的最左边连0个数,来倒推你扔了多少个元素,比如:

扔到目前,我记录的最大左连0个数为3,那么我就有一定的依据推测你扔了23个元素

但是,hyperloglog为了让推算更准确,它采用了一个分桶的机制,我会用很多个桶来分别记录该桶中出现过的最大连零数,然后,利用每个桶的最大连0数倒推基数,并最后将每个桶的倒推基数结果求调和平均值,作为最终推测基数;

12. redis中的订阅和发布

订阅者:

linux01:6379>subscribe channel1

发布者:

linux01:6379> publish channel1 aaa

13 pipeline

13.1 popeline的通信原理:

Redis客户端和服务器之间典型的通信过程可以看作:

  1. 客户端向服务器发送一个命令。
  2. 服务器接收该命令并将其放入执行队列(因为Redis是单线程的执行模型)
  3. 命令被执行。
  4. 服务器将命令执行的结果返回给客户端。

13.2 将一批命令放入一个文件中,通过管道的方式将它们一次性发送,而不再等待每个单独命令的执行结果

1.准备一个文件,用来存放一批命令

[root@doitedu01 ~]# cat pipeline.txt

set a 111

set b 222

sadd set:x v1 v2

get a

scard myset

2.使用redis-cli的--pipe选项,通过管道发送命令:

[root@linux01 redis6]# cat /root/pipeline.txt | bin/redis-cli -h linux01 --pipe

All data transferred. Waiting for the last reply...

Last reply received from server.

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值