一文快速搞定Redis_数据类型及JavaApi操作_redisdeskmanager 搜索userid

bin/redis-server redis.conf


3.2.8 关闭redis



bin/redis-cli -h node1.itcast.cn shutdown


3.2.9 连接redis客户端  
 node1.itcast.cn执行以下命令连接redis服务端



cd /export/server/redis-3.2.8/
bin/redis-cli -h node1.itcast.cn


3.3 Redis Desktop Manager  
 一款基于Qt5的跨平台Redis桌面管理软件,支持:Windows 7+、Mac OS X 10.10+、 Ubuntu 14+,特点: C++ 编写,响应迅速,性能好。  
 下载地址:`http://docs.redisdesktop.com/en/latest/install/#windows`  
 安装客户端,连接本地Redis服务:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210617201333333.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)


备注说明:Redis Desktoo Manager老版本免费,新版本收费。


### Redis的数据类型


redis当中一共支持五种数据类型,分别是:  
 string字符串  
 list列表  
 set集合  
 hash表  
 zset有序集合  
 通过这五种不同的数据类型,可以实现各种不同的功能,也可以应用在各种不同的场景。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210617201404373.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)  
 Redis当中各种数据类型结构如上图:  
 Redis当中各种数据类型的操作


#### 4.1 对字符串string的操作


下表列出了常用的 redis 字符串命令  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2021061720285674.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210617202916335.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)


#### 4.2 对hash列表的操作


Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。  
 Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)


下表列出了 redis hash 基本的相关命令:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210617202953689.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)


#### 4.3 对list列表的操作


list列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)  
 一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。  
 下表列出了列表相关的基本命令:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210617203025604.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210617203045517.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)


#### 4.4 对set集合的操作


Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据  
 Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)[最低时空复杂度,耗时与输入数据大小无关]。  
 集合中最大的成员数为 232 - 1 (4294967295, 每个集合可存储40多亿个成员)。  
 下表列出了 Redis 集合基本命令:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210617203111771.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)


#### 4.5 对key的操作


下表给出了与 Redis 键相关的基本命令:  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/202106172031405.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW55dTEyMA==,size_16,color_FFFFFF,t_70)


#### 4.6 对ZSet的操作


Redis有序集合和集合一样也是string类型元素的集合,且不允许重复的成员  
 它用来保存需要排序的数据,例如排行榜,一个班的语文成绩,一个公司的员工工资,一个论坛的帖子等。  
 有序集合中,每个元素都带有score(权重),以此来对元素进行排序  
 它有三个元素:key、member和score。以语文成绩为例,key是考试名称(期中考试、期末考试等),member是学生名字,score是成绩。


#### 4.7 对位图BitMaps的操作


计算机最小的存储单位是位bit,Bitmaps是针对位的操作的,相较于String、Hash、Set等存储方式更加节省空间  
 Bitmaps不是一种数据结构,操作是基于String结构的,一个String最大可以存储512M,那么一个Bitmaps则可以设置2^32个位  
 Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。可以把Bitmaps想象成一个存储0、1值的数组,数组的每个单元值只能存储0和1,数组的下标在Bitmaps中叫做偏移量


BitMaps 命令说明:将每个独立用户是否访问过网站存放在Bitmaps中, 将访问的用户记做1, 没有访问的用户记做0, 用偏移量作为用户的id 。


##### 4.7.1 设置值


SETBIT key offset value  
 setbit命令设置的vlaue只能是0或1两个值  
 设置键的第offset个位的值(从0算起),假设现在有20个用户,uid=0,5,11,15,19的用户对网站进行了访问, 那么当前Bitmaps初始化结果如图所示


具体操作过程如下, unique:users:2016-04-05代表2016-04-05这天的独立访问用户的Bitmaps  
 setbit unique:users:2016-04-05 0 1  
 setbit unique:users:2016-04-05 5 1  
 setbit unique:users:2016-04-05 11 1  
 setbit unique:users:2016-04-05 15 1  
 setbit unique:users:2016-04-05 19 1  
 很多应用的用户id以一个指定数字(例如10000) 开头, 直接将用户id和Bitmaps的偏移量对应势必会造成一定的浪费, 通常的做法是每次做setbit操作时将用户id减去这个指定数字。  
 在第一次初始化Bitmaps时, 假如偏移量非常大, 那么整个初始化过程执行会比较慢, 可能会造成Redis的阻塞。


##### 4.7.2 获取值


GETBIT key offset  
 获取键的第offset位的值(从0开始算),例:下面操作获取id=8的用户是否在2016-04-05这天访问过, 返回0说明没有访问过  
 getbit unique:users:2016-04-05 8


##### 4.7.3 获取Bitmaps指定范围值为1的个数


BITCOUNT key [start end]


例:下面操作计算2016-04-05这天的独立访问用户数量:  
 bitcount unique:users:2016-04-05


##### 4.7.4 Bitmaps间的运算


BITOP operation destkey key [key, …]  
 bitop是一个复合操作, 它可以做多个Bitmaps的and(交集) 、 or(并集) 、 not(非) 、 xor(异或) 操作并将结果保存在destkey中。 假设2016-04-04访问网站的userid=1, 2, 5, 9, 如图3-13所示:


setbit unique:users:2016-04-04 1 1  
 setbit unique:users:2016-04-04 2 1  
 setbit unique:users:2016-04-04 5 1  
 setbit unique:users:2016-04-04 9 1


例1:下面操作计算出2016-04-04和2016-04-05两天都访问过网站的用户数量, 如下所示。  
 bitop and unique:users:and:2016-04-04\_05 unique:users:2016-04-04 unique:users:2016-04-05  
 bitcount unique:users:2016-04-04\_05  
 例2:如果想算出2016-04-04和2016-04-03任意一天都访问过网站的用户数量(例如月活跃就是类似这种) , 可以使用or求并集, 具体命令如下:  
 bitop or unique:users:or:2016-04-04\_05 unique:users:2016-04-04 unique:users:2016-04-05  
 bitcount unique:users:or:2016-04-04\_05


#### 4.8 对HyperLogLog结构的操作


##### 4.8.1 应用场景


HyperLogLog常用于大数据量的去重统计,比如页面访问量统计或者用户访问量统计。  
 要统计一个页面的访问量(PV),可以直接用redis计数器或者直接存数据库都可以实现,如果要统计一个页面的用户访问量(UV),一个用户一天内如果访问多次的话,也只能算一次,这样,我们可以使用SET集合来做,因为SET集合是有去重功能的,key存储页面对应的关键字,value存储对应的userid,这种方法是可行的。但如果访问量较多,假如有几千万的访问量,这就麻烦了。为了统计访问量,要频繁创建SET集合对象。


Redis实现HyperLogLog算法,HyperLogLog 这个数据结构的发明人 是Philippe Flajolet(菲利普·弗拉若莱)教授。Redis 在 2.8.9 版本添加了 HyperLogLog 结构。


##### 4.8.2 UV计算示例


node1.itcast.cn:6379> help @hyperloglog


PFADD key element [element …]  
 summary: Adds the specified elements to the specified HyperLogLog.  
 since: 2.8.9


PFCOUNT key [key …]  
 summary: Return the approximated cardinality(基数) of the set(s) observed by the HyperLogLog at key(s).  
 since: 2.8.9


PFMERGE destkey sourcekey [sourcekey …]  
 summary: Merge N different HyperLogLogs into a single one.  
 since: 2.8.9


Redis集成的HyperLogLog使用语法主要有pfadd和pfcount,顾名思义,一个是来添加数据,一个是来统计的。为什么用pf?是因为HyperLogLog 这个数据结构的发明人 是Philippe Flajolet教授 ,所以用发明人的英文缩写,这样容易记住这个语法了。


下面我们通过一个示例,来演示如何计算uv。  
 node1.itcast.cn:6379> pfadd uv user1  
 (integer) 1  
 node1.itcast.cn:6379> keys \*


1. “uv”  
 node1.itcast.cn:6379> pfcount uv  
 (integer) 1  
 node1.itcast.cn:6379> pfadd uv user2  
 (integer) 1  
 node1.itcast.cn:6379> pfcount uv  
 (integer) 2  
 node1.itcast.cn:6379> pfadd uv user3  
 (integer) 1  
 node1.itcast.cn:6379> pfcount uv  
 (integer) 3  
 node1.itcast.cn:6379> pfadd uv user4  
 (integer) 1  
 node1.itcast.cn:6379> pfcount uv  
 (integer) 4  
 node1.itcast.cn:6379> pfadd uv user5 user6 user7 user8 user9 user10  
 (integer) 1  
 node1.itcast.cn:6379> pfcount uv  
 (integer) 10  
 HyperLogLog算法一开始就是为了大数据量的统计而发明的,所以很适合那种数据量很大,然后又没要求不能有一点误差的计算,HyperLogLog 提供不精确的去重计数方案,虽然不精确但是也不是非常不精确,标准误差是 0.81%,不过这对于页面用户访问量是没影响的,因为这种统计可能是访问量非常巨大,但是又没必要做到绝对准确,访问量对准确率要求没那么高,但是性能存储方面要求就比较高了,而HyperLogLog正好符合这种要求,不会占用太多存储空间,同时性能不错


pfadd和pfcount常用于统计,需求:假如两个页面很相近,现在想统计这两个页面的用户访问量呢?这里就可以用pfmerge合并统计了,语法如例子:  
 node1.itcast.cn:6379> pfadd page1 user1 user2 user3 user4 user5  
 (integer) 1  
 node1.itcast.cn:6379> pfadd page2 user1 user2 user3 user6 user7  
 (integer) 1  
 node1.itcast.cn:6379> pfmerge page1+page2 page1 page2  
 OK  
 node1.itcast.cn:6379> pfcount page1+page2  
 (integer) 7


##### 4.8.3 HyperLogLog为什么适合做大量数据的统计


Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。  
 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。  
 但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。


什么是基数?  
 比如:数据集{1, 3, 5, 7, 5, 7, 8},那么这个数据集的基数集{1, 3, 5, 7, 8},基数(不重复元素)为5。基数估计就是在误差可接受的范围内,快速计算基数。


### Redis Java API操作[重点]


Redis不仅可以通过命令行进行操作,也可以通过JavaAPI操作,通过使用Java API来对Redis数据库中的各种数据类型操作。


#### 创建maven工程并导入依赖



redis.clients jedis 2.9.0 junit junit 4.12 test org.testng testng 6.14.3 test org.apache.maven.plugins maven-compiler-plugin 3.0 1.8 1.8 UTF-8

#### API操作



package cn.itcast.redis.api_test;

import org.junit.Test;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class RedisTest {
private JedisPool jedisPool;
private JedisPoolConfig config;
/*5.3 连接以及关闭redis客户端
因为后续测试都需要用到Redis连接,所以,我们先创建一个JedisPool用于获取Redis连接。此处,我们基于TestNG来测试各类的API。使用@BeforeTest在执行测试用例前,创建Redis连接池。使用@AfterTest在执行测试用例后,关闭连接池。

实现步骤:
1.创建JedisPoolConfig配置对象,指定最大空闲连接为10个、最大等待时间为3000毫秒、最大连接数为50、最小空闲连接5个
2.创建JedisPool
3.使用@Test注解,编写测试用例,查看Redis中所有的key
a)从Redis连接池获取Redis连接
b)调用keys方法获取所有的key
c)遍历打印所有key*/
@BeforeTest
public void redisConnectionPool(){
config = new JedisPoolConfig();
config.setMaxIdle(10);
config.setMaxWaitMillis(3000);
config.setMaxTotal(50);
config.setMinIdle(5);
jedisPool = new JedisPool(config, “node1.itcast.cn”, 6379);
}

@Test
public void testConnect() {
    Jedis jedis = jedisPool.getResource();
    Set<String> keySet = jedis.keys("\*");
    for (String s : keySet) {
        System.out.print(s + " ");
    }
}

/\*5.4 操作string类型数据

1.添加一个string类型数据,key为pv,用于保存pv的值,初始值为0
2.查询该key对应的数据
3.修改pv为1000
4.实现整形数据原子自增操作 +1
5.实现整形该数据原子自增操作 +1000*/
@Test
public void stringOpTest() {
Jedis connection = jedisPool.getResource();
// 1. 添加一个string类型数据,key为pv,初始值为0
connection.set(“pv”, “0”);

    // 2. 查询该key对应的数据
    System.out.println("原始pv为:" + connection.get("pv"));

    // 3. 修改pv为1000
    connection.set("pv", "1000");
    System.out.println("修改pv为:" + connection.get("pv"));

    // 4. 实现整形数据原子自增操作 +1
    connection.incr("pv");
    System.out.println("pv自增1:" + connection.get("pv"));

    // 5. 实现整形该数据原子自增操作 +1000
    connection.incrBy("pv", 1000);
    System.out.println("pv自增1000:" + connection.get("pv"));

}

/\*5.5 操作hash列表类型数据

1.往Hash结构中添加以下商品库存
a)iphone11 => 10000
b)macbookpro => 9000
2.获取Hash中所有的商品
3.新增3000个macbookpro库存
4.删除整个Hash的数据*/
@Test
public void hashOpTest() {
Jedis connection = jedisPool.getResource();
// 1. 往Hash结构中添加以下商品库存
// a) iphone11 => 10000
// b) macbookpro => 9000
connection.hset(“goodsStore”, “iphone11”, “10000”);
connection.hset(“goodsStore”, “macbookpro”, “9000”);

    // 2. 获取Hash中所有的商品
    Map<String, String> keyValues = connection.hgetAll("goodsStore");
    for (String s : keyValues.keySet()) {
        System.out.println(s + " => " + keyValues.get(s));
    }

    // 3. 修改Hash中macbookpro数量为12000
    // 方式一:
    // connection.hset("goodsStore", "macbookpro", "12000");
    // 方式二:
    connection.hincrBy("goodsStore", "macbookpro", 3000);
    System.out.println("新增3000个库存后:macbookpro => " + connection.hget("goodsStore", "macbookpro"));

    // 4. 删除整个Hash的数据
    connection.del("goodsStore");
}

/\*5.6 操作list类型数据

1.向list的左边插入以下三个手机号码:18511310001、18912301231、18123123312
2.从右边移除一个手机号码
3.获取list所有的值*/
@Test
public void listOpTest() {
Jedis connection = jedisPool.getResource();
// 1. 向list的左边插入以下三个手机号码:18511310001、18912301231、18123123312
connection.lpush(“telephone”, “18511310001”, “18912301231”, “18123123312”);

    // 2. 从右边移除一个手机号码
    connection.rpop("telephone");

    // 3. 获取list所有的值
    List<String> telList = connection.lrange("telephone", 0, -1);
    for (String tel : telList) {
        System.out.print(tel + " ");
    }
}


/\*5.7 操作set类型的数据

使用set来保存uv值,为了方便计算,将用户名保存到uv中。
1.往一个set中添加页面 page1 的uv,用户user1访问一次该页面
2.user2访问一次该页面
3.user1再次访问一次该页面

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

/*5.7 操作set类型的数据
使用set来保存uv值,为了方便计算,将用户名保存到uv中。
1.往一个set中添加页面 page1 的uv,用户user1访问一次该页面
2.user2访问一次该页面
3.user1再次访问一次该页面

[外链图片转存中…(img-cUnRZyPt-1714280343396)]
[外链图片转存中…(img-9XMH5WA7-1714280343396)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值