撸鸭撸 Redis入门第二章

Set (集合)

set中的值是不能重复的。 sadd myset "hello" #添加一个值 smembers myset # 查看指定set值
sismember myset hello #判断某一个元素是否在set中 scard myset # 获取集合中的元素个数值 srem
myset a1 #移除set指定元素 set是无序,不重复集合 srandmember myset #随机抽set元素 spop
myset #随机删除set元素 smove sa sb a1  #将一个库里指定的值移动到另一个库里 微博、B站,共同关注!(并集)
数字集合类: • 差集 sdiff k1 k2   • 交集 sinter k1 k2  • 并集 sunion k1 k2 
微博,A用户将所有关注的人放到一个set集合中!将他的粉丝也放到一个集合中 共同关注、共同爱好、二度好友(六度分割理论)

Hash (哈希)

适合对象的存储,string 更加适合字符串存储。
map集合,key-,value>(集合) 
hset myhash filed1 kuang #存储 
hget myhash filed1 #获取 
hmset myhash filed1 f1 filed2 f2 #存储多个值 
hmget myhash filed1 filed2 #获取多个值 
hgetall myhash #获取所有的值 
hdel myhash filed1 #删除hash指定的段
hlen myhash #获取hash表的字段数量 
hexists myhash filed1  #指定值是否存在 
hkeys myhash #获取所有的key 
hvals myhash  #获取所有的值 
hincrby myhash mynumber 1 #数量累加 
hincrby myhash mynumber -1 #数量累减 
hsetnx myhash fi4 ff  #如果不存在则可以设置,存在不可设置 list 

ZSet(有序集合)

比set多了排序,存储班级成绩表,工资表等 普通消息,1 重要消息 2 权重判断 排行榜 范围查询
zset k1 score  v1 #在set基础上增加了一个值
zadd salary 2500 xiaoming  #添加值 
zrangebyscore salary -inf +inf #从小到大排序,显示名称 
zrevrange salary 0 -1 #从大到小排序,显示名称
zrangebyscore salary -inf +inf withscores #从小到大排序,显示值和名称 zrangebyscore salary -inf 2000 withscores #2000一下值升序 zrem salary liu
#移除值 zrange salary 0 -1 #查看集合所有值 
zcard salary #获取有序集合的个数 
zcount salary 1 10000 #获取指定区间的指定数量 

geospatial(地理位置)

思考:朋友的定位,附近的人,打车的距离计算?
规则:两级无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入!
有效的纬度从-85.05112878度到85.05112878度。
当坐标位置超出上述指定范围时,改命令会返回一个错误
ERR invalid longitude,latitude pair 31.230000,121.470000
添加数据: 值 纬度 经度 名称
geoadd china:city 116.40 39.90 beijing
geoadd china:city 121.47 31.23 shanghai
geoadd china:city 106.50 29.53 chongqi 114.05 22.52 shengzhen
geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
geopos china:city beijing #获取指定城市的经度和纬度
geodist china:city beijing shanghai km #查看北京到上海直线距离m km 
我附近的人?(获得所有人的地址,定位。)通过半径进行搜索
georadius china:city 110 30 500 km #获取指定经度纬度 500km以内数据
georadius china:city 110 30 500 km withdist #展示具体距离
georadius china:city 110 30 500 km withcoord #展示经度纬度
georadius china:city 110 30 500 km withcoord count 1 #显示指定数量数据
georadiusbymember china:city beijing 1000 km #找出指定位置周围的其他元素
geohash china:city beijing chongqi#将二维的字符串转换为一维的字符串
GEO底层就是zset!所以我们可以使用zset命令实现。
hyperloglog
简介:
redis 2.8.9 就更新了 hyperloglog数据结构!
基数统计算法!
页面访问量,
一个人访问一个网站多次,但是还是算作一个人。
传统方式 set用户id,自动去重
如果保存大量用户id,则比较麻烦。我们的目的是记数,而不是保存用户id。
优点:占用的内存是固定的,2^ 64 不同的元素基数,只需要费12kb内存!
如果要从内存角度考虑,hyperloglog就是首选
0.81% 错误率,统计UV任务,可以忽略不计的!
pfadd mykey a  b c d e f g h i j  #创建一组元素
pfcount mykey #查询一组元素数量
pfmerge mykey3 mykey myketto #合并两组元素生成新一组,去重,并集
如果允许容错,那么一定使用hyperloglog !
如果不允许容错,就使用set或自己的数据类型即可。

bitmaps

位运算。
统计疫情感染人数: 0 00 0 1 0  1 0 
统计用户信息,活跃人数,不活跃,登陆,未登录人数。
位图(数据结构)操作二进制位来进行记录,0 1 两个状态
setbit sign 0 0 # 周一打卡
setbit sign 1 0 # 周二打卡
getbit sign 4 #查看指定天数打卡情况
bitcount sign #显示打卡天数

事务命令版

原子性:mySql:ACID 要么全部成功,要么全部失败
Redis单条命令是保证原子性了,但Redis事务是不支持原子性的。
事务的本质:一组命令的集合!
悲观锁:很悲观,认为什么时候都会出问题,无论做什么都会加锁。
乐观锁:很乐观认为什么都不会出问题,所以不会上锁,更新数据的时候去判断一下,在此期间是否有人修改数据
获取version ,更新时比较version
监视:watch  可以写乐观锁,本身就是乐观锁

jedis

是官网推荐java开发工具,使用Java操作Redis的一个中间键先说说jedis(底层) 
  1. 导入jedis包
<dependencies>
    
    <dependency>
        <groupId>redis.clientsgroupId>
        <artifactId>jedisartifactId>
        <version>3.2.0version>
    dependency>
    
    <dependency>
        <groupId>com.alibabagroupId>
        <artifactId>fastjsonartifactId>
        <version>1.2.62version>
    dependency>
dependencies>

2.编码测试
• 连接数据库
• 操作命令
• 断开连接 jedis.close();

事务代码版

public static void main(String[] args) {
        Jedis jedis = new Jedis("127.0.0.1",6379);
        //所有的命令就是之前所有指令,掌握指令很重要
        System.out.println(jedis.ping());//测试连接 PONG
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("hello","www");
        jsonObject.put("name","kkk");
        jedis.flushDB();
        Transaction multi = jedis.multi();//开启事务
        String string = jsonObject.toJSONString();
        try {
            multi.set("user1",string);
            multi.set("user2",string);
            int i = 1/0;//代码跑出异常事务,执行失败!
            multi.exec();//执行事务
        } catch (Exception e) {
            multi.discard();//放弃事务
            e.printStackTrace();
        } finally {
            System.out.println(jedis.get("user1"));
            System.out.println(jedis.get("user2"));
            jedis.close();
        }
    }

springboot整合

springboot操作数据:spring-data jpa jebc mongodb redis!   
springDate和SpringBoot也是齐名的项目!
springboot 所有配置类都在 spring-boot-autoconfigure-2.5.3.jar 中 spring.factories 文件里
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")//我们可以自己定义一个redisTemplate来替换这个默认的
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    //默认的RedisTemplate 没有过多配置,redis对象都是需要序列化的!
    //两个泛型都是object,object类型,后使用需要强制转换,
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}
//由于string类型是很常用的类型,所以就单独提出一个bean
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
}

整合测试一下

  1. 导入依赖
<dependency>
     <groupId>org.springframework.bootgroupId>
     <artifactId>spring-boot-starter-data-redisartifactId>
dependency>
  1. 配置连接
spring.redis.host=127.0.0.1
spring.redis.port=6379
  1. 测试!

    默认为jdk序列化!
    首先redis存储需要进行序列化,使用jar包自带 redisTemple 默认使用的是jdk进行序列化代理,可充写redisTemple方法更换序列化模式,序列化后存储key为非其他格式拼接字符,正常存储

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        //为了开发方便一般直接使用 
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        //Json序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //String 的序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}
所有的Redis操作,对于开发者来说,十分简单,更重要的是去理解redis的思想和每一种数据结构的用处和作用场景!

Redis.conf详解

配置文件 unit单位对大小写不敏感
包含文件、就好比我们学的spring 、import 、include 导入文件
bind 绑定ip
protected-mode yes #保护模式
port 6379 #端口设置
GENERAL #通用配置
daemonize yes #以守护进程的方式运行,默认是no
pidfile /var/run/redis_6379.pid #如果以后台方式运行,我们就需要指向一个pid文件!
默认 notice #生产环境
logfile "" #日志的文件路径名
databases 16 #默认16个数据库
always-show-logo no #是否总是显示LOGO
SNAPSHOTTING 快照 (持久化)
在规定的时间内,执行了多少操作,则会持久化一个文件,.rdb .aof 文件
redis是内存数据库,如果没有持久化,那么数据就会断电即失!
如果在3600秒内 至少有1个key进行了修改,我们就进行持久化操作
# save 3600 1
如果在300秒内 至少有100个key进行了修改,我们就进行持久化操作
# save 300 100
如果在60秒内 至少有10000个key进行了修改,我们就进行持久化操作
# save 60 10000
我们之后学习持久化,会定义这个测试!
stop-writes-on-bgsave-error yes #持久化如果出错,是否还需要工作
rdbcompression yes #是否压缩rdb文件,需要消耗cpu文件
rdbchecksum yes #保存rdb文件时,检查校验
dbfilename dump.rdb #rdb文件保存目录
REPLICATION  复制,~主从复制再扯
SECURITY 安全 默认无密码
CLIENTS 客户端
maxclients 10000 #最大客户端连接数量
maxmemory  #redis配置最大内存容量
maxmemory-policy noeviction #内存到达上线处理策略

redis 中的默认的过期策略是 volatile-lru

1、volatile-lru:只对设置了过期时间的key进行LRU(默认值) 
2、allkeys-lru : 删除lru算法的key   
3、volatile-random:随机删除即将过期key   
4、allkeys-random:随机删除   
5、volatile-ttl : 删除即将过期的   
6、noeviction : 永不过期,返回错误
Redis持久化
Redis发布订阅
Redis主从复制(哨兵模式)
Redis缓存穿透和雪崩

你可能感兴趣的:(学习,redis)