Redis基本操作

安装Redis

docker-compose安装—单节点

version: "3.3"
services:
    master:
      image: redis:6.0
      container_name: redis
      environment:
        - "discovery.type=single-node"
      command: redis-server --port 6379 --requirepass liuy13141@  --appendonly yes
      restart: always
      ports:
        - 6379:6379
      volumes:
        - /home/redis/data:/data 

Redis命令

select 1; 选择1号DB
DBSIZE; 当前选择DB大小
set name “liuy” 设置key:value
get name 获取key 的value
keys * 查看所有Key
flushall 清空全部DB的key
flushdb 清空当前DB的Key

Redis单线程

redis基于内存操作,CPU不是Redis性能瓶颈。
Redis瓶颈:机器的内存和网络贷款
每秒10w+的QPS
数据操作速度:CPU>内存>硬盘

Redis单线程为什么快?

redis所有数据都存放内存中,所有单线程操作起来快,多线程会存在CPU上下文切换耗时操作,对于内存系统而言,没有上下文切换就是效率最高。多次读写都在一个CPU上。

数据类型

  • String

    • 在key原有value后面追加value

      APPEND key value .

    • 获取字符串长度

      STRLEN key

    • incr key 自增1
      decr key 自减1
      INCRBY key 10 自增步长10
      DECRBY key 10 自减步长10

    • 获取字符串范围值

      GETRANGE key 0 9 0~-1表示获取全部

    • 替换指定位置开始的字符串

      SETRANGE key 1 “liuy”

    • 分布式操作

      setex key 20 “liuy” 设置 过期时间
      setnx key “liuy” 如果key不存在创建key,如果存在创建失败
      msetnx key1 value1 key2 value2 同时设置多个值,原子操作要不全部成功,要么就失败。

    • 同时获取多个值

      mget key1 key2

    • 设置对象

      mset user:uuid:name zhangsan user:uuid:age :22
      设置对象值user:{id}:{filed}

    • 先get再set

      getset key value 先get再set 如果不存在返回nil,存在返回原来值,再设置新值。 更新操作

  • List 适合两端操作,消息队列

    • 插入list

      LPUSH Llist one/two/three 从头开始插入
      RPUSH Rlist one/two/three 从尾开始插入

    • 出list

      Lpop Llist -->one 从头开始移出
      Rpop Llist -->three从尾开始移出

    • 获取list所有值

      LRANGE list 0 -1

    • 通过下标获取值

      Lindex list 1 获取下标1的list值

    • 返回list长度

      Llen list 返回list长度

    • 移除list中指定值

      lrem list 2 one 移除list中2个为one的值

    • 通过下标截取指定长度list

      ltrim list 1 2 list只保留截取的元素

    • 移除list最后一个元素,push到另外一个list中

      rpoplpush list newlist; 返回移除的元素

    • 替换list指定下标的值

      lset list 0 “123” 如果下标0存在就更新值,不存在报错:index超出

    • 将value插入到指定元素的前面或后面

      linsert list before “world” “other” 把other插入到list前面
      linsert list after"world" “other” 把other插入到list后面面

  • Set set不可重复 共同好友

    • 添加

      sadd myset value

    • 查看指定set所有值

      SMEMBERS myset

    • 判断value是否存在

      SISMEMBER myset value 存在–1 不存在–0

    • 获取set集合中元素个数

      scard myset

    • 移除set集合指定value

      srem myset hello 移除集合中的hello

    • 随机获取元素

      SRANDMEMBER myset
      SRANDMEMBER myset 2 随机两个元素

    • 随机移除元素

      spop myset

    • 移除指定值到另一个set集合

      smove myset myset2 “movevalue”

    • 共同好友,并集

      SDIFF setkey1 setkey2 差集
      SINTER setkey1 setkey2 交集 共同好友
      SDIFF setkey1 setkey2 并集

  • Hash Map 集合–key:value 处理对象

    • 插入

      hset hashname hashkey hashvalue
      hmset hashname hashkey hashvalue hashkey hashvalue

    • 获取

      hget hashname hashkey
      hmget hashname hashkey hashkey
      hgetall hashname

    • 删除指定key,对应value也没有了

      hdel hashname hashkey

    • 获取hash表key数量

      hlen hashname

    • 判断hash中指定key存在

      hexists hashname hashkey

    • 获取所有key,value

      hkeys hashname
      hvals hashname

  • Zset 排序集合 排行榜

    • 添加

      zadd ZsetName 1 value
      zadd ZsetName 2 value1 3 value2

    • 排序

      ZrangeBySCORE ZsetName -inf +inf 从小到大
      ZrangeBySCORE ZsetName -inf 5000 withscores 升序到5000并显示key
      ZREVRANGE ZsetName 0 -1 降序

    • 移除Zset指定元素

      zrem ZsetName value

    • 获取Zset中元素个数

      zcard ZsetName

设置key有效期

EXISTS key 判断key存在 1 存在-0 不存在
move key 移除 key
EXPIRE key 10 设置key10秒过期
ttl key key剩余时间过期
type key 当前key类型

Geospatial 地理位置

底层采用Zset,可用zset命令操作
经纬度查询

  • 添加地理位置 纬度,经度 ,名称

    geoadd china:city 39.90 116.40 beijin

  • 获取指定城市的经度纬度

    geopos china:city beijing chongqin 返回坐标值

  • 获取两地的直线距离

    geodist china:city beijing shanghai km

  • 附近的人(半径查询)

    georadius china:city 110 30 1000 km 【withdist 距中心距离】【withcoord 经纬度】【count 1 查询个数】
    以110,30 经纬度为中心 1000km半径内的城市

  • 找指定元素周围坐标 —定位

    geoRadiusByMember china:city beijing 1000km 北京1000km内的东西

Hyperloglog 基数统计(允许容错)

优点: 占用内存固定,264不同的元素技术,12KB内存。
一个人访问一个网站多次,记作一次。

PFadd mykey1 p1 p2 p3 p4 p5 p6 创建第一组用户
PFadd mykey2 p2 p7 p3 p8 p5 p10 创建第二组用户
PFMERGE mykey3 mykey1 mykey2 合并1和2 ==> key3
PFCOUNT key3 并集数量

Bitmaps(统计两种状态的数据)

位运算储存
记录是否签到,只需要46字节就能存储365天数据
365天=365bit 1B=8bit 365/8=46个B

setbit person1 1 1; 用户1 第一天签到
setbit person1 2 1; 用户1 第二天签到
setbit person1 3 0; 用户1 第三天未签到
setbit person1 4 1; 用户1 第四天签到

查看某天签到情况

getbit person1 3—>0
getbit person1 4—>1

统计签到天数

bitcount person1—>3

事务

Redis事务:一组命令的集合,一个事务中所有命令的都会被序列化,在事务执行过程中,顺序执行,保证一次性,顺序性,排他性。
Redis没有事务隔离级别概念。
Redis事务中,并不是直接执行,要发起执行命令才执行
Redis只保证单条命令的原子性,事务不保证。

事务过程: 开启事务(multi),命令入队,执行事务(exec)。
执行完成后 ,一组事务就结束。

放弃事务(DISCARD) ,队列中命令全部取消

  • 编译时异常(代码问题),事务中所有命令都不会执行
    1. mulyi 开启事务
    2. set key1 v1 :入队成功
    3. getset key1 :命令报错,仍可继续加入事务队列 .
    4. exec :事务执行时会编译报错,所有命令都不会执行
  • 运行时异常(1/0) ,其他命令正常执行,错误命令抛出异常
    1. mulyi 开启事务
    2. set key “v1” :入队成功
    3. incr key:将key1的值自增,此时命令编译不会报错(执行时:String格式自增会报错)。
    4. exec :事务执行时会抛出错误,但其他命令正常执行

乐观锁

通过比较version,判断是否有人修改数据。

监视过程中,如果有其他线程修改监视的值,那后面的事务一定失败;

  1. UNWATCH 事务执行失败,先解锁
  2. watch money; 获取最新值,监视money;
  3. multi 开启事务
  4. DECRBY money 10 取钱10
  5. INCRBY money 100 存钱 100
  6. exec; 比较监视器中的值

jedis与lettuce

jedis:采用直连,多线程操作,不安全;如果需要避免线程不安全,使用jedis pool 连接池,类似BIO模式。
lettuce:采用netty,实例可多线程中共享,不存在线程不安全;可减少线程数据,类似NIO模式。

Redis常用配置

######网络配置##########
# 指定 redis绑定的IP地址,如果不进行设置,那么将处理所有请求
bind 127.0.0.1

#保护模式,默认开启。
protected-mode yes

# 端口号
port 6379

######通用配置##########
# 守护进程方式运行,默认no
daemonize yes  

#以后台方式运行指定pid进程文件
pidfile /var/run/redis_6379.pid

# 日志
#debug(记录所有日志信息,适用开发阶段)
#verbose(记录大部分日志信息)
#notice(适当的日志信息,适合生产环境,默认级别)
#warn(只有记录非常重要的信息)
loglevel notice

# 日志文件的位置
logfile /usr/local/redis.log

############快照###############
#持久化,规定时间内执行多少次操作,就会持久化到文件
save 900 1   #900s 内,至少一个key进行修改,则进行持久化
save 300 10  #300s 内,至少10个key进行修改,则进行持久化
save 60 10000  #60s 内,至少10000个key进行修改,则进行持久化

#持久化出错后,是否继续工作 默认开启
stop-writes-on-bgsave-error yes

#压缩RDB文件,消耗一定的CPU资源 默认开启
rdbcompression yes

#保存RDB文件时,进行错误检查校验   默认开启
rdbchecksum yes

# RDB、AOF生成的当前目录
dir ./

############安全###############
# 设置密码   默认没有密码
# 密码得有点难度,redis认证密码太快了
requirepass foobared

#######附加模式##############
#aof持久化模式,默认关闭
appendonly no
appendfilename "appendonly.aof"

#同步数据
#always   每次修改都会sync同步,消耗性能
#everysec  每秒执行一次,可能丢失这一秒数据
#no  不执行sync,由操作系统同步数据,速度最快
appendfsync everysec

Redis持久化

RBD快照(默认)

持久化:指定时间间隔将内存的数据集快照写入硬盘,恢复时将快照文件直接读到内存中。

RDB持久化过程:单独创建(fork)一个子进程进行持久化,将内存中的数据写入临时RDB文件中,待持久化过程结束,再用这个临时文件替换上次的持久化文件。

整个持久化过程中,主进程不进行任何IO操作,保证性能。
因为RDB需要时间,所有最后一次的持久化数据可能丢失。

设置密码config set requirepass “”

触发机制

  • save规则满足情况,触发RDB
  • 执行flushall命令,触发RDB
  • 退出redis,触发RDB

恢复RDB文件

  • config get dir #找到redis启动目录
  • xxx.rdb 放到redis启动目录中,自动检查rdb恢复其中数据。

优点

  • 适合大规模的数据恢复
  • 对数据完整性要求不高

缺点

  • 需要一定时间间隔进程操作
  • 如果redis意外宕机,最后一次修改的数据就丢失了
  • fork子进程的会占用一定的内存空间

AOF

AOF持久化过程:单独创建(fork)一个子进程进行持久化,根据内存中数据快照,将改变数据的每个写命令以日志的形式记录,只追加到AOF文件中,redis重启会读取文件重新构建数据(所有指令全部执行一次)。

修复aof文件

  • redis-check-aof --fix appendonly.aof

优点:

  • 每次修改都同步,文件完整性更好
  • 每秒同步一次,可能丢失一秒数据
  • 从不同步,效率最高
    缺点:
  • aof远远大于rdb文件,修复速度比rdb慢。
  • aof运行效率比rdb慢,会进行大量IO操作。

扩展:

  1. RDB持久化方式能指定时间间隔内对数据进行快照存储。

  2. AOF持久化方式记录每次对服务器的写操作,当服务器重启时重新执行这些命令来恢复数据,AOF命令以Redis协议追加保存每次写的操作到文件末尾,Redis还能对AOF文件进行后台重写,使得AOF文件体积不至于过大。

  3. 只做缓存,可以不用持久化。

  4. 同时开启两种持久化方式

    • Redis重启会优先载入AOF文件来恢复数据,通常情况AOF文件保存数据比RDB的数据集更完整。
    • RDB更适合备份数据库,AOF文件不断变化可能出现BUG,不易备份。
  5. 性能

    • RDB文件只做后备用途,建议在Slave上持久化RDB文件 。
    • 开启AOF,好处:最恶劣情况也只是丢失不操作2秒数据,代价:带来持续的IO操作,rewrite产生新数据带来的阻塞。
    • 关闭AOF,仅靠Master-Slave Repllcation实现高可用,好处:省掉IO,减少rewrite带来系统波动。代价:主从同时宕机,会丢失十几分钟数据。启动脚本会比较主从中RBD文件,载入较新的那个。

Redis主从复制(一主三从)

默认情况:每台redis都是主机。只需要配置从机。
主从复制:将一台主服务器上的数据复制到其他从服务器,数据复制单向的,只能从主节点到从节点,Master以写为主,Slave以读为主。

作用:

  1. 数据冗余:实现数据的热备份,持久化之外的一种数据冗余方式。
  2. 故障恢复:主节点故障,从节点提供服务,实现快速故障恢复;实际上一种服务的冗余。
  3. 负载均衡:主从复制基础上,配合读写分离,主节点负者写服务,从节点负者读服务,分担服务器负载。
  4. 高可用的基石:哨兵和集群的实施基础。

环境配置:
通过命令配置,只生效一次,重启即失效。

  1. 拷贝配置文件

    cp redis.conf redis6379.conf
    cp redis.conf redis6380.conf
    cp redis.conf redis6381.conf
    cp redis.conf redis6382.conf

  2. 修改port、pidfile、logfile、dbfilename

    pidfile /var/run/redis_6379.pid
    port 6379
    logfile “redis_6379.log”
    dbfilename dump6379.rdb

  3. 只配置从机

    slaveof 127.0.0.1 6379 从机连接到6379端口的主机
    slaveof no one 自己就是主机
    info replication 查看redis信息

  4. 完成主写从读

复制原理:

  1. Slave启动连接master后发送一个Sync同步命令
  2. Master接到命令,启动后台的存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,master将整个数据文件传送到slave,并完成一次完全同步。
  3. 全量复制:slave接收到数据文件后,将其存盘并加载到内存。自动执行。
  4. 增量复制:master继续将的所有收集到的修改命令依次传给slave,完成同步。

Redis哨兵(自动选举主机)

  1. 基础配置文件sentinel.conf

    sentinel monitor redis 127.0.0.1 6379 1
    redis 被监控名称
    host
    port
    1 主机挂了,自动投票选出主机

  2. 启动哨兵

    redis-sentinel sentinel.conf

优点:

  1. 哨兵集群,基于主从复制模式
  2. 主从切换,故障可以转移,系统可用性更好
  3. 哨兵模式就是主从模式升级,自动选取主机
    缺点:
  4. Redis不好在线扩容,集群容量达到上限,在线扩容麻烦。
  5. 哨兵模式配置多。

Redis缓存穿透和雪崩

缓存穿透

缓存穿透:redis缓存中没有命中,再向数据库中查询,也没有。导致查询失败。大量请求都这种状态,会给数据库造成很大压力,这就是缓存穿透。

解决方案:

  1. 布隆过滤器

    一种数据结构,对所有可能查询的参数以hash形式存储,在控制层先校验,不符合则丢弃,避免对底层存储系统造成压力。

  2. 缓存空对象

    即使查到的数据为空,也缓存起来。
    浪费空间,造成数据不一致问题。

缓存击穿

缓存击穿:缓存中的热点数据在大并发情况下,突然失效,造成大量并发直接请求服务器。好像在墙上凿了一个洞。
解决方案:

  1. 热点数据key永不过期
  2. 分布式锁

    对于每个key同时只能一个线程去查询后端服务,其他线程没有获得分布式锁就等待。将高并发压力转换到分布式锁。

缓存雪崩

缓存服务断网
解决方案:

  1. redis高可用

    异地搭建集群

  2. 限流降级

    缓存失效后,通过加锁或者队列控制读数据库的线程数量。

  3. 数据预热

    正式部署前,将热点数据预先访问一遍,设置不同过期时间,让失效时间尽量均匀。

回答: Redis数据库是一个内存数据库,通过key-value键值对的方式进行数据存储。它的优点包括访问速度快、适用于缓存系统和存储大量活跃数据,可以提高网站的响应速度。\[1\]在Java中,有两个比较出名的连接Redis的驱动包,分别是Jedis和Redisson,我们可以使用Jedis来进行程序操作Redis。\[3\]以下是一些基本的Redis操作方法: - 使用`new Jedis(host, port)`创建Jedis对象,其中host是Redis服务器地址,port是Redis服务端口。 - 使用`set(key, value)`方法设置字符串类型的数据。 - 使用`get(key)`方法获取字符串类型的数据。 - 使用`hset(key, field, value)`方法设置哈希类型的数据。 - 使用`hget(key, field)`方法获取哈希类型的数据。 - 使用`lpush(key, values)`方法设置列表类型的数据。 - 使用`lpop(key)`方法从列表左侧弹出元素。 - 使用`rpop(key)`方法从列表右侧弹出元素。 - 使用`del(key)`方法删除指定的key。\[3\] #### 引用[.reference_title] - *1* [redis基本操作](https://blog.csdn.net/m0_50782114/article/details/128119748)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Redis基本使用!](https://blog.csdn.net/weixin_50769390/article/details/127134134)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值