学习日志day64(2021-11-02)(1、Redis配置文件 2、Redis的发布和订阅 3、Redis的新数据类型 4、Redis Jedis 测试 5、Redis事务)

学习内容:学习Redis(Day64)

1、Redis配置文件
2、Redis的发布和订阅
3、Redis的新数据类型
4、Redis Jedis 测试
5、Redis事务


1、Redis配置文件

(1)开头定义了一些基本的度量单位,配置大小单位,只支持bytes,不支持bit,大小写不敏感

(2)网络相关配置,找到bind变量
默认情况bind=127.0.0.1只能接受本机的访问请求,不写的情况下,无限制接受任何ip地址的访问,服务器是需要远程访问的,所以需要将其注释掉。

(3)本机访问保护模式设置,将protected-mode设置为no

(4)在宿主机Windows环境上安装RedisDesktopManager,可以用来访问虚拟机上的Redis数据库。

(5)设置密码
在Redis终端查看密码config get requirepass,设置密码config set requirepass "123456",此时再执行操作会提示输入密码,输入密码auth 123456后才能继续操作。

在命令中设置密码,只是临时的。重启redis服务器,密码就还原了。
永久设置,需要再配置文件中进行设置。在# requirepass foobared下面添加requirepass 密码。

2、Redis的发布和订阅

(1)打开一个客户端订阅channel1SUBSCRIBE channel1,打开另一个客户端,给channel1发布消息hellopublish channel1 hello,返回的1是订阅者数量,打开第一个客户端可以看到发送的消息。
注:发布的消息没有持久化,如果在订阅的客户端收不到hello,只能收到订阅后发布的消息。

3、Redis的新数据类型

(1)Redis提供了Bitmaps这个“数据类型”可以实现对位的操作:
Bitmaps本身不是一种数据类型, 实际上它就是字符串(key-value) , 但是它可以对字符串的位进行操作。
Bitmaps单独提供了一套命令, 所以在Redis中使用Bitmaps和使用字符串的方法不太相同。 可以把Bitmaps想象成一个以位为单位的数组, 数组的每个单元只能存储0和1, 数组的下标在Bitmaps中叫做偏移量。
setbit<key><offset><value>设置Bitmaps中某个偏移量的值(0或1)(*offset:偏移量从0开始)
getbit<key><offset>获取Bitmaps中某个偏移量的值

(2)求集合中不重复元素个数的问题称为基数问题。
解决基数问题有很多种方案:
1.数据存储在MySQL表中,使用distinct count计算不重复个数
2.使用Redis提供的hash、set、bitmaps等数据结构来处理
以上的方案结果精确,但随着数据不断增加,导致占用空间越来越大,对于非常大的数据集是不切实际的。Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。

pfadd <key>< element> [element...] 添加指定元素到 HyperLogLog 中,将所有元素添加到指定HyperLogLog数据结构中。如果执行命令后HLL估计的近似基数发生变化,则返回1,否则返回0。

pfcount<key> [key ...] 计算HLL的近似基数,可以计算多个HLL,比如用HLL存储每天的基数,计算一周的基数可以使用7天的基数合并计算即可

pfmerge<destkey><sourcekey> [sourcekey ...] 将一个或多个HLL合并后的结果存储在另一个HLL中,比如每月活跃用户可以使用每天的活跃用户来合并计算可得

(3)geoadd<key>< longitude><latitude><member>[longitude latitude member...] 添加地理位置(经度,纬度,名称),实例:geoadd china:city 106.50 29.53 chongqing 114.05 22.52 shenzhen 116.38 39.90 beijing
两极无法直接添加,一般会下载城市数据,直接通过 Java 程序一次性导入。
有效的经度从 -180 度到 180 度。有效的纬度从 -85.05112878 度到 85.05112878 度。
当坐标位置超出指定范围时,该命令将会返回一个错误。
已经添加的数据,是无法再次往里面添加的。

geopos <key><member> [member...] 获得指定地区的坐标值。

geodist<key><member1><member2> [m|km|ft|mi ] 获取两个位置之间的直线距离
单位:
m 表示单位为米[默认值]。
km 表示单位为千米。
mi 表示单位为英里。
ft 表示单位为英尺。
如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位

georadius<key>< longitude><latitude>radius m|km|ft|mi 以给定的经纬度为中心,找出某一半径内的元素

4、Redis Jedis 测试

(1)Jedis所需要的jar包

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
</dependency>

(2)创建测试程序

package com.atguigu.jedis;
import redis.clients.jedis.Jedis;
public class Demo01 {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.241.200",6379);
        String pong = jedis.ping();
        System.out.println("连接成功:"+pong);
        jedis.close();
    }
}

Jedis-API: Key

jedis.set("k1","v1");
jedis.set("k2", "v2");
jedis.set("k3", "v3");
Set<String> keys = jedis.keys("*");
System.out.println(keys.size());
for (String key : keys) {
    System.out.println(key);
}
System.out.println(jedis.exists("k1"));
System.out.println(jedis.ttl("k1"));                
System.out.println(jedis.get("k1"));

Jedis-API: String

jedis.mset("str1","v1","str2","v2","str3","v3");
System.out.println(jedis.mget("str1","str2","str3"));

Jedis-API: List

jedis.lpush("mylist","v1","v2","v3");
List<String> list = jedis.lrange("mylist",0,-1);
for (String element : list) {
    System.out.println(element);
}

Jedis-API: set

jedis.sadd("orders","order01");
jedis.sadd("orders","order02");
jedis.sadd("orders","order03");
jedis.sadd("orders","order04");
Set<String> smembers = jedis.smembers("orders");
for (String order : smembers) {
    System.out.println(order);
}
jedis.srem("orders","order02");

Jedis-API: hash

jedis.hset("hash1","userName","lisi");
System.out.println(jedis.hget("hash1","userName"));
Map<String,String> map = new HashMap<String,String>();
map.put("telphone","13810169999");
map.put("address","atguigu");
map.put("email","abc@163.com");
jedis.hmset("hash2",map);
List<String> result = jedis.hmget("hash2","telphone","email");
for (String element : result) {
    System.out.println(element);
}

Jedis-API: zset

jedis.zadd("zset01",100d, "z3");
jedis.zadd("zset01", 90d,"l4");
jedis.zadd("zset01", 80d,"w5");
jedis.zadd("zset01", 70d,"z6");
Set<String> zrange = jedis.zrange("zset01", 0, -1);
for (String e : zrange) {
    System.out.println(e);
}

完成验证码案例。

5、Redis事务

(1)Redis事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

Redis事务的主要作用就是串联多个命令防止别的命令插队。
输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,Redis会将之前的命令队列中的命令依次执行。组队的过程中可以通过discard来放弃组队。

组队中某个命令出现了报告错误,执行时整个的所有队列都会被取消。
如果执行阶段某个命令报出了错误,则只有报错的命令不会被执行,而其他的命令都会执行,不会回滚。

(2)悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制。
乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。

启用乐观锁,使用WATCH 命令对所有 key 进行监视:
在执行multi之前,先执行watch key1 [key2],可以监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
关闭乐观锁,使用UNWATCH 命令取消 对所有 key 的监视。
如果在执行 WATCH 命令之后,EXEC 命令或DISCARD 命令先被执行了的话,那么就不需要再执行UNWATCH 了。

(3)Redis事务三特性

单独的隔离操作
事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

没有隔离级别的概念
队列中的命令没有提交之前都不会实际被执行,因为事务提交前任何指令都不会被实际执行。

不保证原子性
事务中如果有一条命令执行失败,其后的命令仍然会被执行,没有回滚。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值