Java - 中间件 - Redis

Java - 中间件 - Redis

一、Linux系统下安装Redis

官方下载地址
这里使用6.2.4版本的

https://download.redis.io/releases/redis-6.2.4.tar.gz

wget https://download.redis.io/releases/redis-6.2.4.tar.gz
#获取资源
tar -zxvf redis-6.2.4.tar.gz
#解压资源
cd redis-6.2.4/ 
#进入redis目录下
make MALLO=libc
#因为这是源码文件,通过make MALLO=libc进行编译
...
#一通操作之后,redis建议你先运行一下make test,测试是否有问题
make test
# 运行完之后,出现两个错误
yum install tcl-devel
#根据错误,先安装tcl
make test
#再次测试
...
mkdir redis
#创建一个单独属于redis的安装目录
#进入redis安装包解压的目录下,执行以下代码
make install PREFIX=/data/redis
#将安装路径放到redis文件夹中
cd /data/redis/
#去redis文件夹下发现里面只有一个bin文件见
cp ../redis-6.2.4/redis.conf  redis.conf
#将配置文件拷贝过来
cd /data/redis/bin/
#进入bin目录
 ./redis-server ../redis.conf 
 #启动文件,把配置文件加载进来

ok,到此为止,redis安装完成,不过此时你会发现有很多问题,如下

  • 端口无法访问

firewall-cmd --permanent --zone=public --add-port=6379/tcp
firewall-cmd --reload
firewall-cmd --zone=public --query-port=6379/tcp

  • 只能127.0.0.1(本机)访问

修改配置文件中的bind 127.0.0.1 为0.0.0.0
打开配置文件,通过查找bind ,修改内容

  • 启动之后出现指定页面,没办法关闭

打开配置文件,修改 daemonize no为yes

  • 输入的中午出现乱码

./redis-cli --raw
用这种方式打开redis就可以了

二、常见类型

2.1 String

在String中可以储存三种数据类型,分别是:String字符串Int整数Float浮点数

  • 常见操作
  • get key
    获取对应key的值,如果没有则返回 nil
  • set key value [EX seconds|PX milliseconds] [NX|XX]
    设置键值对,没有键的时候创建,有的时候就覆盖 加ex代表过了几秒这个键值对就删除 加px代表多了多少毫秒就删除,加nx代表存在key的时候修改失败,避免修改已存在数据 xx只有存在key才会修改成功
  • del key
    删除键值对
  • mset key value [key value…]
    批量设置键值对
  • mget key [key…]
    批量返回,在程序中执行时,会以一个list返回
  • strlen key
    获取value的长度,一个汉字占3个长度
  • append key value
    向key后面追加value的内容
  • getrange key start end
    获取指定的长度 ,getrange key 0 -1 返回所有长度 ,下标从0开始 ,从start(包含)到end(包含)结束
  • incr key
    当存储的数据是整型时,对数据进行递增1
  • incrby key value
    指定递增的大小 incrby key 100,一次递增100
  • decr key
    当存储的数据是整型时,对数据进行递减1
  • decrby key value
    指定递减的大小 decrby key 100,一次递减100
  • incrbyfloat key value
    当数据时浮点数时,指定递增的大小 incrbyfloat key 9.1,一次递增9.1,decrbyfloat不存在
  • setbit key index [0|1]
    rdedis中的数据是按8位二进制的形式存储的。set bit可以修改对应位置的二进制值
    修改key中,第index个位置的值为[0或者1]
  • getbit key index
    获取key的第index的位置上的二进制值
  • bitpos key vlaue(0|1)
    查询key对应的值的第一个0或者1的位置
  • bitcount key
    查询这个key对应的值中存在多少个二进制值1
    set a: b :c value
    创建多级目录,可以用来保存对象,但是会消耗大量内存,因为保存的key也很多
  • 应用场合
  1. 用作缓存(以读操作为主的数据)
  2. 分布式session
  3. 通过set nx(唯一限制) 和 ex(过期)实现分布式锁
  4. incr全局ID
  5. incr 全局计数器
  6. incr 限流
  7. 位操作

2.2 Hash

hash内部可以存在多个键值对,但是hash的value只能存储字符串,不可以多重嵌套

  • 与String的区别
  1. 相对String来说,节约了内存空间,因为多个键值对放在了一起
  2. 减少了key冲突的可能
  3. 如果需要批量获取的时候,操作简化,也可以减少cpu消耗
  4. String 可以设置过期时间,hash不可以对内部的键值对设置过期时间,只可以对外层键值对进行过期设置
  5. hash不支持bit操作,无法通过bit运算
  6. 一个hash里面,如果内容太多,会导致redis单个节点容量过大
  • 常见操作
  • hset key field value [field value …]
    设置hash内容,一个key可以包含多个field和value,主要适用于对象
  • hmset key field value [field value …]
    作用同上,可以设置多个hash值
  • hget key field
    获取一个hash里面的指定field的值
  • hmget key field [field …]
    获取一个hash里面的一个或多个指定field的值
  • hincrby key field value
    针对整型数据,指定key的field的值,增加 value大小,使用负进行递减
  • hincrbyfloat key field value
    针对浮点数数据,指定key的field的值,增加 value大小,使用负进行递减
  • hexists key field
    判断某一个field是否剖存在,返回 1 代表存在
  • hdel key
    删除key,仅限于hash
  • hdel key field [field …]
    删除key中的field,仅限于hash
  • hlen key
    返回hash的元素个数
  • 应用场景
  1. 储存复杂对象
  2. 购物车(案例)
    Java - 中间件 - Redis

2.3 List

  • 常用操作
  • lpush key element [element …]
    在左边增加一个或多个元素
  • rpush key element [element …]
    在右边增加一个或多个元素
  • lpop key [count]
    从左边开始取出元素,count是取几个,不写就默认取一个
  • rpop key [count]
    从右边开始取出元素,count是取几个,不写就默认取一个
  • lindex key index
    通过下标获取到对应位置的元素,从0开始,不是取出
  • lrange key start stop
    通过下标范围进行获取数据, 如果stop是-1 ,代表全部获取,不是取出
  • 应用场景
  1. 实现消息队列
  2. 内容时间线(动态、朋友圈)

2.4 Set

存储一个无序的String内容

  • 常用操作
  • sadd key member [member …]
    向集合中增加元素,内容不可重复,增加进去之后并不会按照输入顺序进行排序
  • smembers key
    查询集合中的所有元素,查询结果是无序的
  • scard key
    查询集合长度
  • srandmember key [count]
    随机返回指定长度的元素个数,不加count默认为1
  • spop key [count]
    返回一个(或多个)随机元素,并从集合中删除
  • srem key member [member …]
    从集合中删除指定的元素,可以一次删除多个
  • sismember key member
    判断一个元素是不是集合中的数据,返回0代表不是,返回1代表是的
  • sdiff key [key …]
    只在第一个集合中,不在第二个集合中,不加指定集合就只展示前者集合的数据
  • sinter key [key …]
    在第一个和指定集合中都存在的数据,不加指定集合就只展示前者集合的数据
  • sunion key [key …]
    在集合与指定集合之间合并去重,不加指定集合就只展示前者集合的数据
  • 应用场景
  1. 使用set进行抽奖,spop
  2. 维护一组数据,比如用户点赞
    Java - 中间件 - Redis
  3. 商品标签
    Java - 中间件 - Redis
  4. 商品筛选
    Java - 中间件 - Redis
  5. 用户关注
    通过集合之间的操作,计算关注情况,比如互相关注、关注的人是否关注了他人、可能认识的人等

2.5 ZSet

每一个元素都有一个分值,通过分值排序,如果分值相同,通过key的ASCII进行排序,越小的数据排列越靠前
Java - 中间件 - Redis

  • 常用操作
  • zadd key score member [score member …]
    向ZSet中添加数据,例如:zadd myzset 10 a 20 b 30 c 40 d 50 e,注意分值在前面
  • zrange key min max [WITHSCORES]
    根据下标取出对应元素的内容 ,max为-1,代表全部取出,加上WITHSCORES,则输出分值
  • zrevrange key start stop [WITHSCORES]
    反转取出的内容,分值越大越靠前
  • zrangebyscore key min max [WITHSCORES]
    根据分值进行输出
  • zrem key member [member …]
    删除元素中的内容
  • zcard key
    获取ZSet的数据量
  • zincrby key increment member
    将指定元素的分值增加 increment
    -zrank key member
    获取指定元素的下标
  • zscore key member
    获取元素分值
  • 应用场景
  1. 排行榜

2.6 Geo Spatial(地理位置)

  • 常用操作
  • geoadd key longitude latitude member [longitude latitude member …]
    保存经纬度位置 例如 :geoadd citys 121.48 31.22 sh
  • geopos key member [member …]
    获取一个或多个位置的经纬度
  • geodist key member1 member2 [m|km|ft|mi]
    获取两个位置之间的距离,默认单位是m
  • georadius key longitude latitude radius m|km|ft|mi
    找出在指定范围一定距离内的值,例如:georadius citys 113.01 28.19 5 km
  • georadiusbymember key member radius m|km|ft|mi
    根据city查询一定范围内的值

三、Redis高级功能

3.1 发布订阅

  1. 订阅频道,一次可以订阅多个频道
    subscribe channel [channel …]
  2. 发布内容,向指定频道发布内容
    publish channel message
  3. 取消订阅频道,取消订阅的时候,不可以在已经订阅的界面内取消,因为这个时候已经阻塞了
    unsubscribe [channel [channel …]]
  4. 订阅指定内容的模块
    psubscribe pattern [pattern …]
    例如:psubscribe sports,订阅以sports结尾的频道
    例如:psubscribe news
    ,订阅以news开头的频道
    例如:psubscribe news-weather,订阅news-weather频道

3.2 事务

  • 语法

开启事务:multi
执行事务:exec
取消事务:discard
乐观锁:watch(乐观锁在事务开启之前就需要加上,如果锁定的值发生变化,则事务执行失败)

  • 异常处理
  1. 在执行之前出现的问题:
    这个时候出现的问题会直接报错,事务无法执行
  2. 在执行之后出现的问题:
    这个时候正确语句会被执行,错误语句无法执行,不支持原子性原则
  • 特点
  1. 按事务顺序执行
  2. 不会受到其他客户端的干扰
  3. 不支持数据回滚

3.3 执行lua脚本

  • 特点
  • 优点

    1. 批量执行redis命令,减少网络开销
    2. redis中会将lua的命令视为整体的,可以变相的实现事务的原子性
    3. 通过lua脚本,实现lua脚本的复用
  • 基本用法

    eval script numkeys key [key ...] arg [arg ...]
    # eval 执行命令的起始符
    # script 需要执行的命令,可以是文件,也可以是一行命令
    # numbers 需要的参数的数量,不需要参数的话,设置为0
    # KEYS[1],ARGV[1] 参数显示,lua脚本中,下标是从1开始的
    
  • 使用实例

    eval "return 'hello world'" 0
    #输出   hello world
    
    eval "redis.call('set',KEYS[1],ARGV[1])" 1 qs 2673
    #执行了redis的String的设置值的语句 可以通过get查询到内容
    
  • 执行lua脚本

    ./redis-cli --eval qs.lua 0 
    # ./redis-cli --eval 文件名  参数数量
    
  • 示例

    对某一个ip地址进行限流,即在x秒内只能访问y次

    -- lua脚本
    
    local num = redis.call('incr',KEYS[1])
    --对传过来的用户标识进行递增,如果不存在,则创建一个 1 
    if tonumber(num) ==1 then
        --如果是第一次访问
        redis.call('expire',KEYS[1],ARGV[1])
        --给传过来的用户标识创建过期时间
        return 1
    elseif tonumber(num)>tonumber(ARGV[2]) then
        --如果访问次数大于设置的次数
        return 0
    else
        return 1 
    end
    
  • 将脚本添加到脚本缓存中,避免每次都加载文件

    SCRIPT LOAD script
    ## 此时会返回一个sha值,eval sha值的时候,也是可以使用lua脚本的
    
  • 查看指定的脚本是否已经被保存到缓存中

    SCRIPT EXISTS script [script ...]
    
  • 杀死所有执行中的脚本(脚本超时)

    SCRIPT KILL
    
  • 从脚本缓存中去掉所有的脚本

    SCRIPT FLUSH
    

3.4 批量数据操作

3.5 数据淘汰和内存回收

3.6 数据持久化

上一篇:Python项目(美多商城)_8 hash操作


下一篇:Redis持久化方案