redis(remote dictionary server)学习笔记

本文详细介绍了NoSQL数据库的四大分类及其应用场景,并深入探讨了Redis的安装、配置、性能测试及常见操作命令等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

nosql数据库四大分类

  • kv键值对:redis、menmcache、tair(淘宝自研分布式存储引擎)
  • 文档型数据库(bson格式,类似于json):mangodb、conchdb
  • 列存储数据库:Hbase、分布式文件存储系统
  • 图关系数据库(不是存放图,而是存放的关系,例如社交网络):neo4j、infoGrid

redis的安装

linux下:

  1. 解压redis安装包
  2. yum install gcc -c++(gcc是编译器套件,该命令是下载安装c++编译器)
  3. make(编译)
  4. make install(安装)
  5. 拷贝redis.conf ,编辑配置文件(其中,由于redis默认不是后台启动的,所以需要把配置文件中daemonize:no 改为daemonize:yes)
  6. redis-server 目录/redis.conf (启动redis服务)
  7. redis-cli -h 127.0.0.1 -p 6379 >>ping(客户端直接访问服务,默认IP和端口号,可修改)

redis 性能测试

redis自带的性能测试工具;redis-banchmark
命令:redis-benchmark - h 127.0.0.1 -p 6379 -c 100(100并发数)-n 10000(10000次请求)

redis默认16个数据库

配置文件中有

databases 16

默认使用的是第0个数据库,相关操作命令:

select 3 切换第四个数据库

  • config get databases 查询数据库个数
  • dbsize 查看当前数据库key的数量
  • flush清除当前数据库数据
  • flushall清楚所有数据库中所有数据 # redis是单线程的 redis是内存数据库,cpu不是redis的性能瓶颈,redis的性能瓶颈是网络宽带和内存。所以选择了单线程,而且多线程上下文切换的耗费时间和资源。

key的操作命令

  • keys * 显示所有key
  • get ‘name’ 获取指定key的值
  • set key1 value1 设置添加key的值
  • exists keyname判断指定key是否存在
  • move keyname 1移动到数据库1
  • del keyname 删除key
  • expire keyname 10 设置key的过期时间,单位:秒
  • ttl keyname查看指定key的剩余过期时间,为负数时,表示已过期
  • type keyname查看key的value的数据类型

value的五大基本数据类型

五大数据类型:string、list、set、hash、zset

1、String类型

  • append keyname “hello” 指定key的value后追加字符串,如果指定key不存在,相当于set key1 value1;
  • strlen keyname 获取value字符串的长度;
  • incr keyname 使value数值自增1;
  • decr keyname 使value数值自减1;
  • incrby keyname 10使value数值增加指定的数(博客浏览量动态计数使用);
  • decrby keyname 10使value的值减少指定的数;
  • setex(set with expire)keyname 30 设置过期时间;
  • setnx(set if not exist ) key1 value1 不存在设置(分布式锁中会常用),不存在创建成功,存在创建失败;
  • mset k1 v1 k2 v2 批量set;
  • mget k1 k2批量get;
  • msetnx k1 v1 k3 v3原子性批量set,要么key都不存在,都可以设置成功,要么只要有一个key已存在,就都不可以设置成功;
  • getset k1 v1先反回k1的值,没有则反回null,然后再给key1设置一个姓的值;
  • set user:1 {name:zhangsan,arg:23}设置一个user:1对象,值为json串表示对象;
  • mset user:1:name zhangsan user:1:age 23 批量设置对象属性值;
  • mget user:1:name user:1:age批量获取对象属性值;

2、list

redis中list是链表,有序,可添加重复元素,可以用list实现栈、队列、阻塞队列

  • lpush list1 var1从左端头部添加list元素;
  • lrange list1 0 2 获取list的第1个到第3个元素(lrange list1 0 -1是获取全部元素);
  • rpush list1 var1从右端尾部添加元素
  • lpop list1 var1 移除左端头部第一个元素
  • rpop list1 var移除又短尾部第一个元素
  • lindex list1 0 通过下标获取对应元素
  • llen获取list的长度
  • lrem list1 1 var1 移除匹配指定元素值的1个元素
  • ltrim list1 1 3剪除第二到第四元素之外的其他元素
  • rpoplpush list1 list2 移除list1中最后一个元素,并将这个元素添加到list2中去;
  • lset list1 0 var1将list中指定下标的元素替换,这个key或者对应下标元素不存在时,会失败
  • linsert list1 after/before pivot var1 在元素pivot前或者后插入元素var1;

3、set

无序、不能添加重复元素

  • sadd set1 var1添加元素
  • smembers set1查看set1的所有元素
  • sismember set1 var1 判断指定元素是否在集合中
  • scard set1 获取集合中元素的个数
  • srem set1 var1移除指定元素
  • srandmember set1 n随机抽取出n个元素(srandmember set1随机抽取出一个元素);
  • sdiff set1 set2 求差集(set1有,set2中没有的元素)
  • sinter set1 set2 交集
  • sunion set1 set2 并集

4、hash

理解: 存的是map ,key-map 》key-(field,val),更适合对象的存储
如hset user:1: name zhangsan, set user:1 age 23

  • hset hash1 field1 val1添加元素
  • hget hash1 field1获取元素
  • hmset hash1 field1 var1 filed2 var2添加多个元素
  • hmget hash1 field1 field2获取多个元素
  • hlen hash1获取元素个数
  • hdel hash1 field1删除指定元素
  • hgetall hash1获取所有元素
  • hexists hash1 field1判断指定元素是否存在
  • hkeys hash1 获取所有field
  • hvals hash1 获取所有val
  • hincrby hash1 field1 2
  • hdecrby hash1 field1 2
  • hsetnx

5、zset

有序的set,在set的基础上加了排序
应用场景;排行榜,加权信息

  • zadd zset1 1 val1添加一个元素
  • zadd zset1 2 val2 3 val3添加多个元素
  • zrange zset 0 -1
  • rangebyscore zset1 -inf +inf升序排序(-inf与+inf代表正负无穷)
  • rangebyscore zset1 -inf 3 withscores 序号小于等于3的排序,并显示序号值
  • zrevrange zset1 -inf +inf降序排序
  • zrem zset1 val1移除元素
  • zcard zset1获取元素个数
  • zcount zset1 1 3序号在1到3之间的元素个数

三大特殊数据类型

三大特殊数据类型:bitmaps, hyperloglogs 和 地理空间(geospatial)

1、geospatial

geospatial底层是zset
应用:定位、附近的人、打车距离

将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。这些数据将会存储到sorted set这样的目的是为了方便使用GEORADIUS或者GEORADIUSBYMEMBER命令对数据进行半径查询等操作。
该命令以采用标准格式的参数x,y,所以经度必须在纬度之前。这些坐标的限制是可以被编入索引的,区域面积可以很接近极点但是不能索引。具体的限制,由EPSG:900913 / EPSG:3785 / OSGEO:41001 规定如下:
有效的经度从-180度到180度。
有效的纬度从-85.05112878度到85.05112878度。
当坐标位置超出上述指定范围时,该命令将会返回一个错误。
它是如何工作的?
sorted set使用一种称为Geohash的技术进行填充。经度和纬度的位是交错的,以形成一个独特的52位整数. 我们知道,一个sorted set 的double score可以代表一个52位的整数,而不会失去精度。
这种格式允许半径查询检查的1 + 8个领域需要覆盖整个半径,并丢弃元素以外的半径。通过计算该区域的范围,通过计算所涵盖的范围,从不太重要的部分的排序集的得分,并计算得分范围为每个区域的sorted set中的查询。
使用什么样的地球模型(Earth model)?
这只是假设地球是一个球体,因为使用的距离公式是Haversine公式。这个公式仅适用于地球,而不是一个完美的球体。当在社交网站和其他大多数需要查询半径的应用中使用时,这些偏差都不算问题。但是,在最坏的情况下的偏差可能是0.5%,所以一些地理位置很关键的应用还是需要谨慎考虑。

  • geoadd China:city 116.40 39.90 beijing添加地理位置元素
  • geopos china:city beijing获取经纬度
  • geodist china:city Beijing wuhan km 两个城市之间的距离(m米,km千米、mi英里、ft英尺)
  • georedius china:city 110 30 1000km (加withdist可以显示每个元素与中心点间的直线距离;加withcoord可以显示每个元素经纬度;加count n限制查出元素为n个。)以经纬度110,30的位置为中心查找1000km以内的位置元素
  • georadiusbymember china:city Beijing 1000km 以地理位置元素为中心查询1000km范围内的其他元素
  • gethash china:city beijing 获取元素经纬度的geohash值

2、 hyperloglogs

应用场景:允许一定错误率的计数,比如统计网站访问用户数
优缺点:优点:大数据量占用内存小,2^64元素的基数仅占用12kb;缺点:有0.81%的错误率

  • pfadd hy1 a b c d d 创建一组元素
  • pfcount hy1 获取元素基数(0.81%的错误率)
  • pfmerge hy hy1 hy2 合并hy1与hy2得到并集hy

3、bitmaps

位存储,操作二进制
应用场景:统计用户活跃、不活跃;登陆、未登录;打卡统计;

  • setbit bm1 1 0添加元素
    例如存储一周打卡信息:
    setbit bm1 1 0;
    setbit bm1 2 0
    setbit bm1 3 0
    setbit bm1 4 0
    setbit bm1 5 0
    setbit bm1 6 0
    setbit bm1 7 0
  • getbit bm1 1 或周一是否打卡
  • bitcount bm1 统计状态位1的元素个数

redis事物

redis事物本质是一组命令按顺序执行

  • 开启事物(multi)
  • 命令入队(……)
  • 执行食物(exec)
    discard取消事物
    事物中存在命令编译错误(例如命令写错了),则整个事物无法执行;如果事务中存在运行时异常(例如incr一个非数值型数据),则异常命令执行失败,其他命令执行成功,所以redis事物是不保证原子性的。

乐观锁

set money 100
wacth money加监视器,获取money的值,监控值的变化,实现乐观锁效果
nowatch money去除监视器

jedis

jedis是redis官方推荐的java开发连接工具

  1. 导入对应的jedis依赖
  2. 使用

springboot整合redis

springboot操作数据库数据spring-data(包含jpa、jdbc、redis、mangodb)
springboot2.x之后,原来的jedis被替换成了lettuce
jedis:jedis是直连,多线程下不安全,避免线程不安全,就得使用jedispool,类似bio
lettuce:底层使用了netty,可多线程共享,且线程安全,类似nio;
springboot整合redis

自定义redisTemplate

自定义redisTemplate

redis配置文件详解

redis配置文件详解

持久化rdb与aof

持久化;生成一个数据文件保存到硬盘中

RDB

redis默认的持久化方式,文件:dump.rdb(配置在redis.conf中)

  • 持久化触发条件:
    1、配置文件中save规则满足的情况下
    2、执行flushAll命令
    3、正常退出redis
  • 恢复rdb数据
    只要将rdb文件放到redis启动目录(命令config get dir获取启动目录)中,redis启动时会自动检查加载里面的数据。
  • Rdb持久化优点
    1、 持久化文件将只包含一个文件
    2、 对灾难恢复,主从复制 效率比较高。
    3、 持久化工作:子进程
  • Rdb缺点
    数据安全性不是很好
  • Rdb数据持久化同步策略
    缺省情况下,Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开redis.conf文件之后,我们搜索save,可以看到下面的配置信息:
    • save 900 1 #在900秒(15分钟)之内,如果至少有1个key发生变化(增删改),则dump内存快照。
    • save 300 10 #在300秒(5分钟)之内,如果至少有10个key发生变化,则dump内存快照。
    • save 60 10000 #在60秒(1分钟)之内,如果至少有10000个key发生变化,则dump内存快照。

AOF

以日志记录路写命令到aof文件。
默认配置
在这里插入图片描述
重写规则
aof重写配置

redis默认时不开启AOF持久化的,需手动私改配置

appendonly no 改no为yes 

重启redis后生效

  • 如果aof文件被破坏过,redis重启会失败,这时候可以用redis-check-aof修复文件aof;

  • aof优缺点

  • 2.1、AOF的优点
    (1)AOF可以更好的保护数据不丢失。

一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据,Redis进程挂了,最多丢掉1秒钟的数据;

(2)AOF日志文件以append-only模式写入,写入性能比较高

AOF日志文件以append-only模式写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修;

(3)AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。

因为在rewrite log的时候,会对其中的指令进行压缩,创建出一份需要恢复数据的最小日志出来。再创建新日志文件的时候,老的日志文件还是照常写入。

当新的merge后的日志文件ready的时候,再交换新老日志文件即可。

(4)适合做灾难性的误删除紧急恢复

AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据;

2.2、AOF的缺点
(1)对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大,恢复速度慢;

我们可以简单的认为AOF就是日志文件,此文件只会记录“变更操作”(例如:set/del等),如果server中持续的大量变更操作,将会导致AOF文件非常的庞大,意味着server失效后,数据恢复的过程将会很长;

事实上,一条数据经过多次变更,将会产生多条AOF记录,其实只要保存当前的状态,历史的操作记录是可以抛弃的;因为AOF持久化模式还伴生了“AOF rewrite”。

(2)AOF开启后,支持的写QPS会比RDB支持的写QPS低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的;

如果你要保证一条数据都不丢,也是可以的,AOF的fsync设置成没写入一条数据,fsync一次,那就完蛋了,Redis的QPS大降;

(3)以前AOF发生过bug,就是通过AOF记录的日志,进行数据恢复的时候,没有恢复一模一样的数据出来

所以说,类似AOF这种较为复杂的基于命令日志/merge/回放的方式,比基于RDB每次持久化一份完整的数据快照文件的方式,更加脆弱一些,容易有bug。不过AOF就是为了避免rewrite过程导致的bug,因此每次rewrite并不是基于旧的指令日志进行merge的,而是基于当时内存中的数据进行指令的重新构建,这样健壮性会好很多。

三、RDB和AOF到底该如何选择
1、不要仅仅使用RDB,因为那样会导致你丢失很多数据;

2、也不要仅仅使用AOF,因为那样有两个问题:

你通过AOF做冷备,没有RDB做冷备,恢复速度更快;
第二,RDB每次简单粗暴生成数据快照,更加健壮,可以避免AOF这种复杂的备份和恢复机制的bug;
3、综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择;

用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复

  • 使用方案扩展:
    ……
  • 异地多活

redis发布订阅

  • subscribe demo 订阅端订阅一个频道
  • publish demo “hello” 发送端发送消息

命令:

  1. Redis 配置文件位置查询

    在redis内部执行命令: CONFIG GET *

    一般情况下配置文件叫:redis.conf

  2. ps -ef | grep redis-server 可以查看 redis进程,以及可以查看到安装路径等信息

  3. redis key值获取

    keys * 获取当前数据下所有KEY值

    get key

    set key value 设置key和值

select 2 切换到第二个数据库

  1. info命令

    转自:http://www.runoob.com/redis/server-info.html

    info server : 一般 Redis 服务器信息,包含以下域:

    info clients 表示已连接客户端信息 包含以下内容:

connected_clients 已连接客户端的数量(不包括通过从属服务器连接的客户端)
client_longest_output_list 当前连接的客户端当中,最长的输出列表
client_longest_input_buf 当前连接的客户端当中,最大输入缓存
blocked_clients 正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量
info cpu CPU 计算量统计信息

info mem 内存信息,包含以下:

  • used_memory : 由 Redis 分配器分配的内存总量,以字节(byte)为单位;
  • used_memory_human : 以人类可读的格式返回 Redis 分配的内存总量;
  • used_memory_rss : 从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致;
  • used_memory_peak : Redis 的内存消耗峰值(以字节为单位);
  • used_memory_peak_human : 以人类可读的格式返回 Redis 的内存消耗峰值;
  • used_memory_lua : Lua 引擎所使用的内存大小(以字节为单位);
  • mem_fragmentation_ratio : used_memory_rss 和 used_memory 之间的比率;
  • mem_allocator : 在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc ;
    在理想情况下, used_memory_rss 的值应该只比 used_memory 稍微高一点儿;当 rss > used ,且两者的值相差较大时,表示存在(内部或外部的)内存碎片。内存碎片的比率可以通过 mem_fragmentation_ratio 的值看出。当 used > rss 时,表示 Redis 的部分内存被操作系统换出到交换空间了,在这种情况下,操作可能会产生明显的延迟。当 Redis 释放内存时,分配器可能会,也可能不会,将内存返还给操作系统。

如果 Redis 释放了内存,却没有将内存返还给操作系统,那么 used_memory 的值可能和操作系统显示的 Redis 内存占用并不一致。

查看 used_memory_peak 的值可以验证这种情况是否发生

info persistence RDB 和 AOF 的相关信息

info stats : 一般统计信息

info replication : 主/从复制信息

info commandstats Redis 命令统计信息

info cluster Redis 集群信息

info keyspace redis 数据库相关的统计

info keyspace redis 数据库相关的统计信息

  1. slow log get 10 慢查询语句, 在上一个节中有讲过

    http://www.cnblogs.com/huamei2008/p/8850047.html

  2. Redis自身性能压测:

命令:

redis-benchmark -p 6379 -c 20000 -n 50000

-h 表示IP

-p 表示端口

-c 表示连接数

-n表示请求数

-t 后面跟请求方式, 如get

7、slaveof
slaveof no one 主从复制模式下主节点宕机后,设置从节点为主节点

redis集群

主从复制(一般最低一主二从):
1、主节点写,从节点只能读不能写;
2、主节点的数据会被自动被从节点保存;
主从复制原理
1、slave启动连接到master(未连接成功时,会重复发送请求)
2、slave连接master成功后会发送一个sync同步命令
3、master接收到命令后,启动后台存盘进程,收集所有修改数据集的命令,把数据文件发送给slave,完成一次同步;

  • 完全复制:slave在接受到数据文件后,把数据文件存盘并加载到内存中;
  • 增量复制:master每次数据修改时,会将修改数据的命令发送给slave,salve接受并执行;
    slave每次重新连接上master时,都会发生一次完全复制。

主从复制优缺点:
优点:

  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
  • 为了分载Master的读操作压力,Slave服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成
  • Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。
  • Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
  • Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据

缺点:

  • Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
  • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
  • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

哨兵模式

解决问题:主从复制模式下,主节点宕机后,需要手动修改配置文件或者云命令,影响服务可用性和性能的问题;
原理:哨兵作为一个独立进程,通过向redis服务器发送命令,等待redis服务器响应,从而监控多个redis服务器
,如图:
在这里插入图片描述
实际应用中,为了防止哨兵进程也出现异常停止的情况,通常会启动多个哨兵进程相互监听,如图:
在这里插入图片描述
当主节点宕机时,有一个哨兵发现主节点服务器不可用,这个时候不会发生failover(故障转移),这个现象就是主观下线;只有当发现主节点服务不可用的哨兵超过一定数量时,哨兵间会进行投票在从节点中选出主节点,然后根据投票结果,又一个哨兵进程发起,进行failover操作,修改选出的从节点的配置文件,使之成为主节点,主节点替换成功后,会通过发布订阅的模式,让各个哨兵把监控的这个从节点替换为主节点,这就客观下线

使用:配置文件
sentinel monitor redisname(随意自定义) host port 2(2表示,两个哨兵发现主节点不可用时,执行failover),主节点切换后,原主节点恢复后自动变为从节点。

投票算法。。。。。

缓存穿透、缓存击穿、缓存雪崩及解决方案

1、缓存击穿:某条数据数据在redis缓存中找不到,数据库中也查不到,循环发送请求;
解决方案:

缓存预热、缓存更新、缓存降级

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值