赞
踩
1、方便拓展(数据之间没有关系)
2、大数据量高性能(Redis一秒可以读11万次,写8万次)
3、数据类型多样性(不需要事先设计数据库,随取随用)
Redis
memecache
MongoDB:MongoDB是关系型数据库和非关系型数据库的中间产品,MongoDB是非关系型数据库中功能最丰富,最像关系型数据库的
ConthDB
不是存储图片的数据库,存储的是关系
Neo4j,InfoGrid
Remote Dictionary Server远程数据字典
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。
1、内存存储(断电即失),持久化(RDB、AOF)
2、效率高,可用于高缓存
3、发布订阅系统
4、地图信息分析
5、计时器、计数器
1、数据多样性
2、持久化
3、集群
4、事务
官网:http://www.redis.io/
中文网站:http://www.redis.cn/
1、在网站中下载压缩包
2、将压缩包上传至服务器并解压
tar -zxvf xxx
3、省略。。。
使用测试:
redis-cli -p 6379
keys * 查看所有的key
查看Redis的进程是否启动
ps -ef|grep redis
关闭Redis的服务
在Redis中使用shutdown
redis-benchmark是一个压力测试工具
redis-benchmark 参数
序号 | 选项 | 描述 | 默认值 |
---|---|---|---|
1 | -h | 指定服务器主机名 | 127.0.0.1 |
2 | -p | 指定服务器端口 | 6379 |
3 | -s | 指定服务器 socket | |
4 | -c | 指定并发连接数 | 50 |
5 | -n | 指定请求数 | 10000 |
6 | -d | 以字节的形式指定 SET/GET 值的数据大小 | 2 |
7 | -k | 1=keep alive 0=reconnect | 1 |
8 | -r | SET/GET/INCR 使用随机 key, SADD 使用随机值 | |
9 | -P | 通过管道传输 请求 | 1 |
10 | -q | 强制退出 redis。仅显示 query/sec 值 | |
11 | –csv | 以 CSV 格式输出 | |
12 | -l\(L 的小写字母) | 生成循环,永久执行测试 | |
13 | -t | 仅运行以逗号分隔的测试命令列表。 | |
14 | -I\(i 的大写字母) | Idle 模式。仅打开 N 个 idle 连接并等待。 |
Redis有16个数据库,默认使用第0个
select 3 #切换数据库
DBSIZE #查看数据库大小
flushdb #清空当前数据库
flushall #清空所有数据库
Redis为什么是单线程的:Redis的瓶颈不在于CUP,在于内存和网络带宽,既然单线程可以实现,那么就使用单线程,而且单线程可以节省掉切换线程所带来的开销
Redis为什么单线程还这么快:Redis的数据全部放在内存中,单线程的效率是最高的
exists key #查看key是否存在
move name 1 #移除1号数据库中key为name的数据
expire name 10 #将name的过期时间设置为10秒
ttl name #查看name剩余的过期时间
setex key 10 value #设置key并且设置过期时间
setnx key value #如果不存在key则设置,如果存在,则不设置
mset k1 v1 k2 v2 #批量设置多个值
mget k1 k2 #批量获取多个值
msetnx #批量如果不存在设置(原子性,要么全部成功,要么全部失败)
String
append name “hello” #向key为name的值后面追加字符串“hello”
strlen name #显示key为name的值的长度
incr num #自增
decr num #自减
incrby num 10 #增加10
getrange name 0 3 #截取前4个字符
getrange name 0 -1 #获取key为name的全部值
getset key value #先get再set
List
所有List相关的命令都是以L开头的
List底层数据结构为链表
lpush list one two three #将一个或多个值存入链表
rpush #从右边开始插入数据
lrange list 0 -1 #获取链接的所有值,倒序排列
lpop list 2#移除左边2个值
rpop #移除右边第一个值
lindex list 0#根据下标获取数据
llen list #获取链表长度
lrem list 2 three #移除list列表中最后两个three
ltrim list 0 2 #保留前三个数据,其他数据删除
rpoplpush oldlist newlist #将oldlist中最右边的数据移到newlist最左边
lset list 0 newitem #将llist中下标为0的数据更新为newitem
linsert list before three six #在list列表中,在three左边插入一个six
after # 在右边插入
Set
sadd set set1 set2 set3 set2 set4 #向set中批量添加数据
smembers set #查看set中的全部数据
sismember set set3 #查看set中是否存在set3这个值
scard set #获取set的尺寸
srem set set2 set3 #移除set中set2和set3这两个数据
srandmember set 2 #从set中随机获取2个数据
spop set 2 #随机移除2个数据,默认移除一个
smove set set2 set6 # 将set6这个数据从set集合移动到set2这个集合中
sdiff set1 set2 #查看差集,以set1为核心,查看set1在set2中没有的数据
sinter set1 set2 #查看交集
sunion set1 set2 #查看并集
ZSet
有序集合
zadd set 1 value #添加数据,score为1
zrange 0 -1 #显示所有
ZRANGEBYSCORE salary -inf +inf #排序,从负无穷到正无穷根据score进行排序
withscore #显示的结果带上score
zrem salary a #移除zset中的某个值
Hash
key-map
hset map f1 v1 f2 v2 #设置一个hash类型的数据
hget map f1 #取出key为map,filed为f1的值
hgetall map #获取map的所有键值对
hdel map f1 #删除map中key为f1的数据
hlen map #获取map的字段数量
hkeys map #获取所有的key
hvals map #获取所有的value
hincrby、hsetnx
geospatial
地理位置
底层为zset,可以用一些zset的命令如删除
GEOADD #添加城市信息,一般通过java程序直接导入
GEODIST #获取两点之间的距离
- m 表示单位为米。
- km 表示单位为千米。
- mi 表示单位为英里。
- ft 表示单位为英尺。
GEOHASH #将经纬度转为字符串输出
GEOPOS #获取指定的城市经纬度信息
GEORADIUS #查找给定经纬度与距离为半经内所有的值,查找附近的人,可以指定数量
GEORADIUSBYMEMBER #类似于georadius,区别于它个命令是由给定的位置而不是给定的经纬度zrem #删除某个地理位置
hyperloglog
基数统计
使用场景:当一个用户多次访问同一个网站时,只算作一次访问
实现原理:每次用户访问都使用pfadd加入,最后统计的时候只会统计到一次
0.81%的错误率,如果允许容错,可以使用这个方法
redis> PFADD hll1 foo bar zap a #添加数据 (integer) 1 redis> PFADD hll2 a b c foo (integer) 1 redis> PFMERGE hll3 hll1 hll2 #合并数据 OK redis> PFCOUNT hll3 #统计数据 (integer) 6
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
bitmaps
使用场景:统计用户登录状态,是否活跃,打卡等只有两个状态的场景
使用的是位图数据结构,都是使用二进制来存储
setbit bit 0 1 #设置值
getbit bit 0 #获取值
bitcount bit 0 2 #统计,可以指定范围,默认全部
Redis单条命令可以保证原子性,事务不保证原子性
Redis事务没有隔离级别的概念
所有命令在事务中的时候,并没有被执行,只有在事务开始执行的时候才会执行事务中的命令
**Redis事务的本质:**一组命令的集合, 一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行
一次性,顺序性,排他性
Redis事务:开始事务(multi),命令入队(…),执行事务(exec)
discard #取消事务
当执行事务报错场景:
编译型错误(事务中某个命令错误):在执行事务的时候会报错,所有命令都不会执行
运行时异常(给某个不存在的值自增时):错误命令抛出异常,其他命令正常执行
监控 Watch
悲观锁:很悲观,总是考虑最坏的情况,无论什么情况都会加锁
乐观锁:比较乐观,总考虑最好的情况,不会上锁,在更新数据的时候会根据数据的version去判断在此期间是否有人变更过这个数据
Redis的监视测试
#线程一
127.0.0.1:6379> mset money 10
OK
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> INCR money
QUEUED
127.0.0.1:6379(TX)> INCR money
QUEUED
127.0.0.1:6379(TX)> EXEC
(nil)
127.0.0.1:6379>
#线程二
127.0.0.1:6379> set money 300
OK
在线程一对money进行监视,开启事务,对money进行操作并不执行,此时线程二对money进行变更,线程一在执行的时候会执行失败
unwatch money #先取消监视,再重新监视,然后开始事务
导入Jedis的依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.2.3</version>
</dependency>
// 在代码中使用Jedis,和在命令行中使用一样
// 远程调用Redis的时候需要先开启对应端口,其次要修改配置文件的保护功能
private static final String host = "120.27.129.201";
private static final int port = 6379;
public static void main(String[] args) {
Jedis jedis = new Jedis(host,port);
System.out.println(jedis.ping());
jedis.set("name","ralph");
System.out.println(jedis.get("name"));
}
在SpringBoot2.X以后,原来使用的Jedis被替换成了lettuce
**Jedis:**采用的是直连,在多线程调用的情况下不安全,需要使用Jedis pool连接池
**lettuce:**采用的是netty,实例可以在多个线程中共享,不存在线程不安全的情况
1、导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、添加配置
spring:
redis:
host: 120.27.129.201
3、启动测试
4、编写Utils工具类
网络
bind 127.0.0.1 #允许访问的ip
protected-mode yes #受保护的
port 6379 #端口号
通用
daemonize yes #以守护进程的方式运行(后台运行),默认为no
pidfile /var/run/redis_6379.pid #如果以守护进程方式运行,需要指定它的pid文件存储位置
loglevel notice #日志级别
logfile #日志文件
database 16 #数据库数量,默认16
alwayss show-logo yes #是否显示logo
快照
save 900 1 #900秒内如果有一个以上的key进行了修改,则进行持久化
save 300 10 #300秒内有10个以上的key进行了修改,则进行持久化
save 60 10000 #60秒内有10000个以上的key进行了修改,则进行持久化
stop-writes-on-bgsave-error yes #持久化的时候出错是否继续工作
rdbcompression yes #是否压缩rdb文件,需要消耗一些CPU资源
rdbchecksum yes #保存rdb文件的时候是否校验、检查
dir /www/server/redis/ #rdb文件保存目录
复制
安全
Redis默认没有密码,可以设置密码
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) ""
127.0.0.1:6379> config set requirepass 916828
OK
127.0.0.1:6379> config get requirepass
1) "requirepass"
2) "916828"
127.0.0.1:6379> ping
PONG
客户端限制
maxclients 10000 #最大客户端连接数
maxmemory <bytes> #Redis最大内存容量
maxmemory-policy noeviction #内存达到上限后的处理策略(6种拒绝策略)
APPEND ONLY MODE aof配置
appendonly no #默认不开启,使用rdb方式
appendfilename "appendonly.aof" #持久化文件
appendfsync everysec #aof执行策略(三种执行策略)
Redis默认使用RDB进行持久化操作
是指redis隔一段时间将内存中的数据集快照写入硬盘
实际操作过程:fork一个子进程,先将数据集写入一个临时文件,替换掉之前的文件,使用二进制进行压缩存储,文件名:dump.rdb
存储过程中子进程与父进程同步进行,子进程负责备份,父进程负责继续服务
RDB优点
RDB缺点
当redis执行改变数据的命令时,会将这个命令加到AOF文件中,记录所有操作日志
AOF同步策略:1、每秒同步,即每秒同步一次,不过如果系统在这一秒内发生宕机,那么这一秒的变更会丢失;2、每修改同步,即每次修改都会同步,这样效率会很差;3、不同步,不同步修改数据
AOF优点
AOF缺点
序号 | 命令及描述 |
---|---|
1 | [PSUBSCRIBE pattern pattern …] 订阅一个或多个符合给定模式的频道。 |
2 | [PUBSUB subcommand argument [argument …]] 查看订阅与发布系统状态。 |
3 | PUBLISH channel message 将信息发送到指定的频道。 |
4 | [PUNSUBSCRIBE pattern [pattern …]] 退订所有给定模式的频道。 |
5 | [SUBSCRIBE channel channel …] 订阅给定的一个或多个频道的信息。 |
6 | [UNSUBSCRIBE channel [channel …]] 指退订给定的频道。 |
#连接一
SUBSCRIBE ralph #订阅渠道
#实时接收消息
1) "message"
2) "ralph"
3) "hello"
#连接二
PUBLISH ralph hello #在渠道中发送消息
主从复制,就是将一个Redis服务器中的数据,复制到其他Redis服务器中,前者称为主节点,后者称为从节点
数据的复制都是单向的,只能由主节点复制到从节点,主节点以写为主,从节点以读为主
默认情况下每个Redis服务器都是主节点,可以配置它的主节点,且一个从节点只能有一个主节点
在使用redis服务的时候如果时单机服务,一旦单机服务宕机了,那么可能导致我们整个系统处于不可用状态,或者当系统的访问量大了以后单机的redis服务成功了整个系统的瓶颈,这时候就到了主从复制展示伸手的时候了.主从复制可以帮我们完成以下功能.
1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
2.故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
3.负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
4.高可用基石:主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
一般来说,要将Reids应用在工程项目中,只使用一台服务器是不行的(服务器可能会发生宕机)
一般情况下,读的情况远远大于写的情况,所以可以使用一主三从模式
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ygU2vtpi-1666075447394)(…/Image/image-20220629191456212.png)]
info replication #查看服务器配置信息
role:master #表示这是一个主节点
connected_slaves:0 #表示没有从节点
修改配置文件:
1、端口
2、pid名字
3、log文件名字
4、rdb文件名字
在从机上配置主机(命令或者修改配置文件)使用命令行配置的话,重启会失效
slaveof 127.0.0.1 6379
中有主机可以写操作,从机不能写,在主机中写入数据后从机中可以查到
当从机第一次连接到主机时,会发送一个sync命令,主机收到命令后会对从机进行一次全量复制,当从机与主机连接成功后,主机的数据的变更会增量同步到从机称为增量复制
链表模式
链表模式为三个服务器之间依次依赖,呈链表状,如第三个是第二个的从机,第二个是第一个的从机,这样当第一个主机宕机时,可以使用slaveof no one
命令来使得第二个服务器变为主机。
当第一个服务器重新启动后,不能重新回到主机的地位,只能加入到第二个服务器下面,成为一个从机
当主机宕机时,需要手动输入命令去切换主机,需要人工干预,而且可能会导致一段时间服务不可用,Redis从2.8开始提供了sentinel(哨兵)架构来解决这个问题
哨兵模式能够在后台自动监控主机是否出现问题,如果出现了问题,根据投票数自动将从库转为主库
1、配置哨兵配置文件sentinel.conf
# sentinel monitor 被监控的名称 host port 1
# 1代表如果主机挂了,那么进行投票选举新的主机
sentinel monitor myredis 127.0.0.1 6379 1
2、启动哨兵
redis-sentinel sentinel.conf
如果主机宕机了,哨兵会随机(随机算法)在从机中选取一个作为主机,如果原来的主机重启成功,那么会自动成为新主机的从机
描述:一个数据请求,缓存与数据库中都不存在该数据,但是依然高频调用,会导致数据库压力增加
解决方案:可将该key的value设置为null,时间设置短一点以免导致正常时间无法使用
描述:缓存中有数据,请求次数非常多,数据库中有,如缓存到期,此时并发访问会导致数据库压力增加
解决方案:
描述:缓存数据大量同时到期,同时访问数据库导致数据库大力增加
解决方案:多条数据缓存时间设置不一致,避免多条数据同时到期
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/305439
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。