Redis
文档型数据库(bson格式和json)
- MongoDB
- MongoDB是一个基于分布式文件存储的数据库,C++编写,主要用来处理大量文档
- MongoDB 是介于关系型数据库和非关系型数据库之间产品,最像关系型数据库的数据库
概述
Redis 是什么?
Redis(Remote Dictionary Server) 远程字典服务C语言编写
Redis 能干嘛?
- 内存存储、持久化、内存中是断电既失(持久化非常重要rdb、aof)
- 效率高,可以高速缓存
- 发布订阅系统
- 地图信息分析
- 计时器、计数器、浏览量
- ......
特性
- 多样的数据类型
- 持久化
- 集群
- 事物
- .......
学习中用到的东西
1.官网:https://redis.io/
2.中文网:http://www.redis.cn/
Redeis 文件分析
- redis-server.exe:服务端
- redis-cli.exe:客户端
- redis-check-aof.exe:检查持久化
- redis-benchmark.exe:测试性能
redis 默认端口
6379
Linux下安装
-
拷贝压缩包(tar.gz)到linux系统
-
一般情况,我们的程序放在/opt目录
-
tar -zxvf 解压文件
-
进入解压后的文件可以看见redis.conf配置文件
-
yum install gcc-c++(基本运行环境)(gcc -v 查看环境版本)
-
make 命令(把需要的文件全部配置)(需要在解压文件中执行)
-
make install (看下是否安装完成)
-
如果出现(You need tcl 8.5 or newer in order to run the Redis test)
yum -y install wget wget http://downloads.sourceforge.net/tcl/tcl8.6.1-src.tar.gz sudo tar xzvf tcl8.6.1-src.tar.gz -C /usr/local/ cd /usr/local/tcl8.6.1/unix/ sudo ./configure sudo make sudo make install 版权声明:本文为CSDN博主「前尘忆梦Memory」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/zhangchaoyang/article/details/104456978
-
redis的,默认安装路径 /usr/local/bin
-
将redis.conf文件考入bin目录下(保证原有的redis.conf文件干净可用)
-
redis默认不是后台启动,修改配置文件daemonize 默认为no,改为yes(改为后台运行,守护进程)
-
redis-server config/redis.conf(通过后面指定的配置文件启动redis)
-
redis-cli -p 6379 客户端测试连接
-
拓展:ps -ef|grep redis 查看进程 shotdown关闭redis客户端
压力测试
redis-benchmark -h localhost -p 6379 -c 100 -n 100000
并发测试,本机,100个并发,10万个请求
redis 基本知识
- redis中默认有16个数据库,默认使用第一个(select 3)切换到第4个数据库
- get,set获取设置数据
- DBSIZE 查看数据库大小
- keys * 查看当前数据库所有的key
- flushdb清除当前数据库
- flushall清空所有数据库
- exists key 判断某个键是否存在(1,0)
- move key 1 移除当前库
- expire key 10 设置的key10秒后过期,ttl查看还有多久过期
- type key 查看数据的类型
redis 是单线程的!
redis是很快的,redis基于内存操作,cpu不是redis瓶颈,瓶颈是机器内存和网络带宽
- 误区:高性能的服务器一定是多线程
- 误区2:多线程一定比单线程效率高
核心:redis是将所有数据全部放在内存中的,使用单线程是最快的(多线程cpu上下文会不停的切换),多次读写都是在一个cpu上,所以在内存情况下是最快的
redis五大数据类型
-
String (字符串类型)
- append key 追加字串
- strlen key 获取字段长度
- incr key 长度+1(浏览量)
- decr key 长度-1
- incrby key 增量
- decrby key 减量
- getrange key 0 3(获取区间0到3的值截取[0,3]) getrange key 0 -1 全部
- setrange key 1 xx(替换key值,从1位置开始)
- setex key 时间 内容 (set with expire) 设置过期时间(setex key3 30 'hello')
- setnx key 内容 不存在在设置,存在会创建失败(1成功,0失败)
- mset k1 v1 k2 v2 (创建了k1和k2,值为v1和v2)
- mget k1 k2批量获取数据
- msetnx k1 v1 k4 v4批量获取数据(k1有,k4没有,但是不会被创建,因为是原子性操作,要么一起成功,要么一起失败)
- set user:1{name:zhangsan,age:3}(设置一个userjson对象,这样设计需要解析json对象,可以设置成 user:1:name 这样的键,可以直接获取到值)
- getset 先get 后set 如果不存在返回nil,如果存在获取当前值,设置赋予的值
- 场景(计数器,统计多单位的数量,粉丝数,对象缓存储存)
-
List(列表类型)
- 所有的list命令都是l开头的
- lpush key将一个或者多个值加入到列表头部
- rpush key将一个或者多个值加入到列表尾部
- lrange key 0 -1 查看所有值
- lpop key 移除头部第一个
- rpop key 移除尾部第一个
- lindex key 0 获取下标对应的值
- llen key 返回列表的长度
- lrem key 1 value(移除1个值,值为value)
- ltrim key 1 2(截取1到2下标的值)
- rpoplpush list1 list2移除列表中最后一个元素,并且添加到新列表
- lset list 0 item 给list中指定下标更新为item
- linsert list before/after v1 v2(在v1前面/后面插入v2)
- 场景(消息排队,队列,栈)
-
set(集合类型)
- sadd key 添加
- smembers 查看集合
- sismember key value判断某个值是不是在set集合中(0、1)
- scard key 获取集合中的个数
- srem key value移除
- srandmember 随机抽选出一个元素
- spop myset 随机移除元素
- smove key1 key2 value 将一个指定的key移到另一个集合中
- 差集:sdiff key1 key2 (key1和key2中不同的数据)
- 交集:sinter key1 key2 (key1和key2相同的数据)
- 并集:sunion key1 key2 (key1 和key2 所有的元素)
- 场景:例如:所有关注的人放入a,粉丝放b,可以对ab进行操作
-
Hash(哈希类型)
- hset key key1 value1 (在集合key中放入键值对key1 value1(map集合))
- hget key key1 获取key1的值
- hmset key key1 value1 key2 value2 (同时加入多个字)
- hmset key key1 key2 (同时获取多个值)
- hgetall key 获取key里面的所有哈希值
- hdel key key1(删除key1的值)
- hlen key (得到hash里面有多少值(内容长度))
- hexists key key1(判断哈希中的指定字段是否存在)
- hkeys key(获取hash中所有key值)
- hvals key获取哈希中所有values值
- hincrby key key1 1(key1+1)
- hsetnx key key1 value1(key1存在创建失败,不存在则可以设置)
- hash更适合对象的存储
-
Zset(有序集合,在set的基础上增加了一个值)
-
zadd key 1 one (在第一个位置放入one)
-
zrange key 0 1(查看0到1的值)
-
zrangebyscore key -inf +inf withscores(安装key排序,负无穷到正无穷(withscores带上其他参数))
-
zrevrange key 0 -1 从大到小排序
-
zrem key key1(移除key1的值)
-
zcard key 获取有序集合中的个数
-
zcount key 1 2 查看区间1到2的数量
-
场景:set集合,需要排序的,排行榜,工资表排序,消息增加权重
-
三种特殊类型
-
geospatial 地理位置
-
能够推算地理位置的信息,两地之间的距离
-
geoadd key 经度 纬度 城市名称 (添加经纬度)
-
geopos key 城市(获取指定的城市经度纬度)
-
geodist(两人之间的距离m、km、mi、ft)
-
georadius key 经度 纬度 半径(找身边的人,一给定的经度纬度为中心,半径找人)
-
georadius key:city 经度 纬度 距离单位 withdist withcoord count 2(搜索半径内数据,只需要展示2个)
-
georadiusbymember key 城市 1000 km (找出指定元素周围的元素)
-
geohash key 城市(将二维的经纬度转化成字符串)
-
geo底层原理,其实就是zset
-
zrange key 0 -1查看全部经度纬度
-
-
hyperloglog(基数统计的算法(一个人访问一个网站多次,只记录一次,有一定误差))
- 占用的内存是固定的
- pfadd key val1 val2 val3 添加数据(pfcount key(统计数量))
- pfmerge key3 key1 key2 (合并1和2到3(只统计没有的元素))
- 如果不允许容错,可以使用set(保存用户id)
-
bitmaps(活跃不活跃,登录不登录,打卡不打卡)
- 位存储(只有2个状态的,都可以用bitmaps 0 ,1)
- setbit key key1 val1(0 or 1) 设置key的第key1 元素的值
- getbit key key1 查看元素
- bitcount key (统计值为1的)
事务
redis单条命令保存原子性,但是事务不保证原子性!
- redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在执行事务中,会按照顺序执行(一次性、顺序性、排他性)
- redis事务没有隔离级别的概念
- redis事务
- 开启事务(multi )
- 命令入队(入队时候并不会执行,只是把命令保存到队列中)
- 执行事务(exec)
正常执行事务
- 开启multi --》 命令 --》 执行exec(执行完成后,事务会销毁)
- descard 取消事务(放弃事务,事务中的命令不会执行)
- (编译型异常)命令有误,事务中所有命令都不会执行
- (运行时异常)比如1/0 ,错误命令不执行,其他命令执行(所以一组命令没有原子性)
监控(watch)
- 悲观锁
- 认为什么时候都有可能出问题,无论做什么都加锁
- 乐观锁
- 认为什么时候都不会出现问题,所以不会上锁(更新数据的时候去判断一下,在此期间时候有人修改过这个数据,mysql中 是加一个version字段)
- 获取version
- 更新的时候比较version
- watch key(监视一个key)(事物成功后,监控就会自动取消)(先监控,在事物)
- 如果watch更新失败,需要unwatch解锁,然后重新watch上锁
Jedis
-
java使用redis sptingboot2.x之后用的是lettuce
什么是jedis,是redis官方推荐的java连接工具
- jedis:采用直连,是不安全的,使用pool连接池
- lettuce:采用netty,实列可以多线程进行共享,减少线程数据
Redis.conf讲解
单位
- unit单位对大小写不敏感,都可以
包含
- 可以把多个配置文件都配置过来
网络
bind 127.0.0.1 绑定的ip
protected-mode yes(保护模式)
port 6379 端口
通用配置
daemonize yes 以守护进程模式开启,默认是不开启no
pidfile /var/run/redis_6379.pid 如果以后台文件运行,需要指定一个配置文件
loglevel notice(通知模式) 日志
logfile “” 输出日志文件名称
databases 16 数据库数量,默认是16个数据库
always-show-logo yes 是否总是显示logo
快照rdb
持久化,在规定的时间内,执行了多少次炒作,会持久化到文件.rdb.aof
redis是内存数据库,断电既失,所有要持久话
save 900 1 #如果900秒内,如果至少有1个key进行了修改,我们及进行持久化操作
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes 持久化出错了,是否继续工作
rdbcompression yes 是否压缩rdb文件,需要消耗一些cpu资源
rdbchecksum yes 保存rdb文件的时候,进行错误校验
dir ./ rdb文件保存目录
replication复制 主从复制
replicaof 主机地址 主机端口
security 密码设置
config get requirepass 查看密码
config setrequirepass 设置密码
密码登录: auth 密码
限制clients
maxclient 10000 设置连接客户的最大连接数
maxmemory <btytes> redis最大的内存容量
maxmemory-policy noeviction 内存到达上线的处理策略(移除一些过期的key,报错,···)
Append only 模式 aof配置
appendonly no 默认是不开启aof模式的,默认使用rdb方式持久化,大部分情况rdb就够用了
appendfilename “appendonly.aof” 持久化文件的名字
appendfsync eberysec 每秒都同步一次/always每次修改同步数据/no 不同步
持久化rdb
rdb保存的文件是dump.rdp 都是在我们配置文件的快照中保存的
- save条件满足时候,会生成dump.rdb文件
- redis关机会生成
- 执行flushall命令,也会触发
恢复rdb
-
只需要把rdb文件放在redis启动目录下就可以了,自动恢复
-
/usr/local/bin
几乎默认的配置就能正常使用
rdb优点
- 适合大规模数据恢复
- 对数据的完整性要求不高
缺点
-
需要一定的时间间隔操作,如果redis意外宕机了,最后一次数据就没了
-
开启子进程备份数据,会消耗一定的cpu资源
持久化aof操作
- 将我们所有命令都记录下来
- 以日志的形式记录每个写的操作
- 配置之后,需要重新启动redis
- 如果aof文件有错误,redis是不能正常启动的,我们需要修复这个aof文件,redis给我们提供了一个工具redis-check-aof --fix
- (aof默认文件无限制增加,文件会原来越大)重新规则:如果aof文件大于64m,就会fork一个新的进程来将我们的文件重写
优点:
-
每次修改都同步,文件的完整性更加好
-
默认开启的是每秒同步一次,可能会丢失1秒的数据
-
从不同步,效率是最高的
缺点:
- 相对于数据文件来说,aof远远大于rdb,修复比rdb慢
- aof运行效率比rdb慢,所以默认是rdb持久化
订阅发布
-
subscribe 频道 订阅频道
-
publish 频道 发布到频道
-
unsubscribe 频道 取消订阅
-
稍微复杂的消息队列用mq
redis主从复制
info replication 可以看到主从的关系(role:master主机,slaves从机)
- 修改配置(端口,pid文件,log文件,dump.rdb文件名称)
- (需要几个服务器,就需要几个配置文件),全部启动,查看redis服务
- 默认情况所有服务器都是主机,一般情况我们只需要配置从机
- slaveof 主机地址 端口
- 真实的主从配置应该在配置文件中修改,才能永久保存,通过命名,只是暂时的(replicaof 主机地址 主机端口)
- 主机可以写,从机只能读,主机的所有数据都会备份到从机
- 主机断开,从机仍然连接主机,但是不能写的操作,主机恢复后,从机又能获取到主机数据
如果主机泵机了,需要有从机顶上
如果主机断开了连接,可以使用slaveof no one 让自己变成主机,但是缺点是手动执行
哨兵模式(自动选取主机)
如果主机断开了连接,可以使用slaveof no one 让自己变成主机,但是缺点是手动执行,哨兵模式可以解决这一缺点
- 创建配置文件:sentinel.conf
sentinel monitor myredis 主机地址 端口 1(最后面这个1是,如果主机挂了,去投票选新主机)
- 启动哨兵
redis-sentinel 配置文件
优点:
-
所有主从配置优点都有
-
可以自动切换主从机,系统可用性更好
缺点:
- redis不好在线扩容,集群容量一旦达到上线,在线扩容十分麻烦
哨兵集群
- 多个哨兵也需要配置多个端口
- 定义工作目录 dit/tmp
- 配置默认的主机节点
redis缓存穿透(查不到)和雪崩,击穿(查的到,量太大了,访问同一点)
- 穿透解决:布隆过虑器
- 击穿:分布式锁