Redis
文章目录
总体大纲outline
- nosql讲解,非关系型数据库
- 阿里巴巴架构演进
- nosql数据模型
- Nosql四大分类
- CAP
- BASE
- Redis入门
- 五大基本类型
- String
- List
- Set
- Hash
- Zset
- 三种特殊数据类型
- geo
- hyprologlog
- bitmap
- Redis配置文件如何读取
- Redis持久化
- RDB
- AOF
- Redis的一些事务操作
- Redis实现订阅发布
- 消息队列
- Redis主从复制
- 哨兵模式,现在公司中所有的集群都采用哨兵模式
- 缓存穿透,以及解决方式
- 缓存雪崩,以及雪崩方式,微服务一环套一环,可能会导致雪崩
- 基础API之jedis详情
- SpringBoot集成Redis操作
- Redis的实践分析
- 五大基本类型
Nosql
大数据时代,一般的数据库无法进行分析处理了Hadoop
单机SQL时代,更多使用静态网页
- 如果数据量过大,一个机器放不下
- 数据量超过300万时一定要创建索引,数据库现在使用B+Tree,一个机器的内存也放不下
- 数据库访问量比较大,一开始是读写混合的,一个服务器也承受不了
出现这三种情况,就需要升级,但是如果没有这么大的数据量,应该从单机开始
Memcached缓存+MySQL+垂直拆分(读写分离)
网站百80%的操作都是在读,减轻数据库的压力可以使用缓存提高效率,缓存使用什么技术都没所谓
- 发展过程,先是优化数据结构和索引–文件缓存(IO操作)–Memcached(当时最热门的技术)
分库分表+水平拆分+M有SQL集群
使用缓存解决了读的问题,用分集群的方式解决读的问题,数据存在不同的库中
早些年,MySAM使用 表锁,读取一行要将整个表锁起来,十分影响效率,高并发下会出现严重问题
后来转为innodb 行锁
慢慢的就开始使用分库分表来解决写的压力,将表拆分,不同的业务使用不同表,存放在不同的数据库中,不同的业务使用单独的数据库,结合微服务,mysql推出了表分区,但是很少公司使用
Mysql的集群已经满足了那个年代的需求
最近的年代
定位也是一种数据,Mysql的关系型数据库已经不够用了,数据量多,变化快,
非关系型数据库
- Json
- Bson
- 图型数据库
放在缓存中一段时间之后再进行持久化的操作,来保证效率和安全
存储很大的文件,会导致数据表很大效率会变低, 如果有一种专门的数据库来处理这种数据Mysql压力就会变得十分小,研究如何处理这些问题
如果数据量变大,要在对数据库进行更改,增加一行是很难的
用户先访问企业防火墙,到负载均衡的主机,到App服务器,到mysql实例,然后是独立功能的服务器
最后总结为什么要用NoSQL
用户的个人信息、社交网络、地理位置、用户自己生产的数据、用户日志等等数据爆发式的生长,
NoSQL=Not Only SQL 不仅仅是SQL
泛指非关系型数据库,Web2.0的诞生,传统的关系型数据库很难对付Web2.0时代,尤其是超大规模的高并发的社区,
NoSQL在大数据环境下发展十分迅速
要存储的数据不是固定格式,以键值对来控制,Map< String , Object >,数据之间没有关系就很好扩展,Java现在要做面向接口编程也是为了解耦,
使用Redis也是为了高性能,官方的数据读取速度每秒11w次,写8w次
数据类型是多样性的,不需要事先设计数据库,不需要设计键值对,随取随用
传统的RDBMS和NoSQL
传统的RDBMS
- 结构化组织
- sql
- 数据和关系都存储在表中 row column
- 数据定义语言
- 严格的一致性
- 基础的事务
- 。。。。
NoSQL
- 不仅仅是数据
- 没有固定查询语言
- 很多的存储方式,列存储、文档存储、图形存储(社交关系)
- 可以不用满足严格一致性,数据是可以有误差的,要保证的是最终一致性
- CAP定理,和BASE理论
- 高性能、高可用、高可扩展
大数据时代的3V和3高
大数据时代的3V,主要是描述问题的
- 海量的Volume
- 多样的Variety
- 实时Velocity
大数据时代的3高,主要是对程序的要求
- 高并发
- 高可拓(随时水平拆分,机器不足,可用扩展来)
- 高性能
真正在公司中实践一定是:NoSQL+RDBMS一起使用才是最好的
阿里巴巴框架演进
第五代架构改进
- 敏捷开发
- 极限编程
- 业务快速增长,每天都要上线大量的小需求
- 应用系统日益膨胀,耦合恶化,架构越来越复杂,带来更高的开发成本,如何保持业务开发的敏捷性
- 开放,提升网站的开放性,吸引第三方开发者加入网站的建设
- 体验,网站并发压力快速增长,用户对体验提出了更高的要求
- 使用了各种数据库,这么多种类型的数据库导致数据架构非常复杂,要简化架构,增加一层就行,像是jdbc一样,
- 商品中的信息存在不同的数据库中
- 商品的基本信息
- 名称、价格、商家信息:
- 关系型数据库就可以解决 MySQL / Oracle
- 淘宝早些年就去IOE了,去掉IBM小型机,Oracle数据库,EMC存储设备
- 名称、价格、商家信息:
- 商家的描述、评论(文字比较多)
- 文档型数据库,MongoDB,
- 图片
- 分布式文件系统,FastDFS
- 淘宝自己的TFS
- Google的GFS
- Hadoop HDFS
- 阿里云的 oss
- 商品的关键字
- 搜索引擎
- solr
- elasticsearch
- 淘宝用的是 Isearch
- 搜索引擎
- 商品热门的波段信息
- 内存数据库
- Redis 、Tair 、Memacache
- 商品的交易,外部支付接口
- 第三方应用
大型互联网应用问题:
- 数据类型太多
- 数据源繁多,经常重构
- 数据要改造,大面积改造
阿里的解决方案
统一数据服务层UDSL,在网站应用集群和底层数据源之间,构建一层代理,统一数据层
- 模型数据映射
- 实现 业务模型 各属性 与 底层不同类型数据源的模型数据映射
- 统一的查询和更新API
- 提供了基于业务模型的统一的查询和更新的API,简化网站应用跨不同数据源的开发模式
- 性能优化
- 设计了一套统一的DSL,提供了统一的增删改查的API,开发速度问题是解决了,但是性能还是问题
- 网站数据庞大,只能缓存热点数据,解决方案,开发热点缓存平台,提供UDSL作为缓存系统
- 以上都是NoSQL入门概述
NoSQL的四大分类
KV键值对
- 新浪:Redis
- 美团:Redis+Tair
- 阿里,百度:Redis+memecache
文档型数据库(Bson格式和Json格式)
- MongoDB
- MongoDB是一个基于分布式文件存储的数据库,C++编写,用来处理大量的文档
- MongoDB是一个介于关系型数据库和非关系型中间的产品,非关系型数据库中功能最丰富的,最像关系型数据库的
- ConthDB
列存储数据库
- HBase
- 分布式文件系统
图形关系数据库
- 不是用来存放图形的,是用来寸关系的,朋友圈社交,广告推荐
- Neo4j,InfoGrid
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sls3Tt2O-1606726398799)(https://gitee.com/haoyunlwh/Typoraimage/raw/master/img/20201112164506.png)]
Redis入门
Redis (Remote Dictionary Server),远程字典服务
开源、使用C语言编写,支持网络、基于内存可持久化的日志型,Key-Value数据库,提供多种语言的API,可以用多种语言调用 ,NoSQL技术之一,也被称之为结构化数据库之一
读的速度是11w,写的速度是8w
Redis能干嘛
- 内存存储,持久化,内存是断电即失的,持久化很重要, 持久化有两种机制(RBD,AOF)
- 效率高,可以用于高速缓存
- 发布订阅系统
- 地图信息分析
- 计数器,(浏览量)
- 。。。
特性
- 多样的数据类型
- 持久化
- 集群
- 事务
- 。。
常用网站
- Redis官网 https://redis.io
- Redis中文网https://www.redis.net.cn
启动Redis
-
安装Redis
-
brew install redis //安装redis brew info redis //查看软件详细信息,以来关系,注意事项等 brew list redis 安装包所在的位置
-
启动Redis
-
redis-server
-
-
启动之后不要关闭
-
连接测试
-
redis-cli
-
默认端口是6379
-
基本操作
-
-
Redis推荐使用Linux开发
-
好吧这里加入了Linux的知识,要开始学习Linux
-
退出Redis
-
redis-cli shutdown
CentOS7 安装Redis
常用的命令
netstat -lnpt |grep 6379
//查看6379=端口占用情况,netstat CentOS不自带,需要另外安装
yum install -y net-tools
kill -9 [PID]
//结束对应PID进程
ln -s /usr/local/redis/bin/redis-cli /usr/bin/redis
//创建链接,使之可以直接使用/bin之中的命令,这创建应该回到~目录进行创建,称为命令软链接
cp /usr/local/redis-5.0.3/redis.conf /usr/local/redis/bin/
//复制操作
make install PREFIX=/usr/local/redis
//安装到指定目录
tar -zxvf redis-5.0.3.tar.gz
//解压
wget http://download.redis.io/releases/redis-5.0.3.tar.gz
//通过链接下载
主要操作
不同版本的redis有不同的操作,选择高版本的redis,基本就只是解压,安装,选择配置文件启动
make install
make uninstall
https://www.cnblogs.com/heqiuyong/p/10463334.html
- 安装gcc
- 下载安装包
- 解压安装包
- 进入安装包
- 执行编译
- 安装到指定目录
- 启动
- 前台启动
- 后台启动
- 设置开启自启动
- 创建开机自启动文件.service
- 创建自启动链接
- 服务操作命令
- systemctl start Redis.service
- … stop …
- restart
- status
- … enable … 设置开机自启动
- … disable …
5.连接redis,redis
Redis测试性能
在/usr/local/bin 下有很多工具
benchmark压力测试工具,官方自带的性能测试工具
- -h 指定服务器主机名
- -p 指定服务器端口
- -c 指定并发连接数
- -n 指定请求数
测试100个并发,每个并发100000个请求
redis-benchmark -p 6379 -c 100 -n 10000
不加-h 就默认本机
解读测试数据
- 10000个set请求使用0.17秒
- 每次请求都有100个并行的客户端
- 每次写入三个字符串
- 只有一台服务器来连接
- 下面的是每毫秒处理百分之多少的请求,
- 每秒能处理五万多次请求
基础知识
Redis是单线程的,Redis是基于内存操作的,CPU不是Redis的瓶颈,根据机器的内存和网络带宽的,可以用单线程实现
每秒10w+的QPS,完全不比使用key-value的Memecache差
单线程Redis
- 误区1,高性能服务器一定是多线程
- 误区2,多线程一定比单线程效率高
- 多线程要涉及CPU的上下文切换
- 核心:Redis是将所有数据全部放到内存中去操作,效率就是高,CPU上下文切换是耗时的操作,对于系统来说没有上下文切换,系统效率就是最高的,多次读写都是在一个cpu上的,在内存情况下效率就是最高的
Redis五大数据类型
- String
- List
- Set
- Hash
- Zset
Redis官方介绍
- Redis是内存中的数据结构存储系统,可以作用数据库、缓存、消息中间MQ
- 支持多种数据类型
- String字符串
- hash散列
- list列表
- set 集合
- sorted sets有序集合
- bimemaps
- hyperloglog
- geospatial
- Redis内置了主从复制replication、LUAscripting脚本,LRU 驱动事件,transactions事务,和不同级别的磁盘持久化persistence
- 通过Redis哨兵Sentinel,和自动分区Cluster,提供高可用性high availability
Redis
-
redis-server & #后台启动 redis-server /etc/local/bin/redis.conf #指定文件启动 -p #指定端口启动
-
keys * 查询全部key
-
select 3 切换数据库3
-
dbsize 查看数据库大小
-
flushdb 清空当前库
-
flushall 清空所有数据
-
exists 判断某个key是否存在
-
move 移除key
-
expire 设置过期时间,可以用作单点登录
-
ttl 查看过期时间
-
type 查看key的类型
-
config set requirepass XXX 设置密码
- config set requirepass “” 取消密码
-
auth xxx 登录
String
-
append 追加value
- 追加不存在的key会set key
-
strlen 查看value长度
-
incr 自增1,可以用作增加浏览量increase
-
decr decrease 递减
-
incrby 能设置自增量的自增
-
getrange 截取范围,下标从0开始
-
setrange 修改范围的值
-
setex set wth expire 设置key时顺便设置生存时间
-
setnx ( set if not exist )参数不存在就设置,在分布式锁经常使用,如果存在就创建失败
-
mset 批量设置,空格间隔
-
mget
-
msetnx 原子性操作,批量设置
-
对象操作
-
127.0.0.1:6379> mset user:1:name lwh user:1:age 3 OK 127.0.0.1:6379> mget user:1:name user:1:age 1) "lwh" 2) "3" 127.0.0.1:6379>
-
设置一个对象,值为json字符串来保存一个对象
-
user:{id}:{filed}
-
-
getset 先get再set,规则就按getset来,无论key存不存在,都按getset来
List
在Redis中可以将List作为、栈、队列、阻塞队列
- 实际上是一个链表,left、right 都可以插入值
- 如果key不存在,创建新的链表
- 如果key存在,新增value
- 移除所有值,空链表
- 在两边插入效率最高,对中间元素操作,效率会降低
消息排队、消息队列、堆、栈
- lpush left push
- lrange 显示list 范围range
- rpush right push
- Rpop right pop
- Lpop left pop
- Llen listlength
- lrem remove指定下标
- ltrim trim截取
- Rpoplpush pop再push到别的list
- lset 设置指定下表值
- exists 存在
- Linsert 将某个具体的value插入到某个元素的前面或后面
#=======================================================================
# lpush、lrange、Rpush
127.0.0.1:6379> lpush list one #插入队列左边
(integer) 1
127.0.0.1:6379> lpush list two
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1 #获取全部的值从0到-1,这是作为栈的最顶上的为index 0,
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> rpush list Right
(integer) 4
127.0.0.1:6379> lrange list 0 -1 #插入队列右边
1) "three"
2) "two"
3) "one"
4) "Right"
########################################################################
#Rpop、Lpop 移出元素 lindex 获取下标对应值
127.0.0.1:6379> rpop list
"Right"
127.0.0.1:6379> lindex list 2
"one"
########################################################################
# 返回llen 长度\ lrem 移除
127.0.0.1:6379> llen list
(integer) 3
127.0.0.1:6379> lrem list 2 three #lrem key count value 移除几个,从左边删除的
(integer) 1
########################################################################
#ltrim 截取范围,其余的删除
127.0.0.1:6379> rpush list l1
(integer) 1
127.0.0.1:6379> rpush list l2
(integer) 2
127.0.0.1:6379> rpush list l3
(integer) 3
127.0.0.1:6379> rpush list l4
(integer) 4
127.0.0.1:6379> ltrim list 2 3
OK
127.0.0.1:6379> lrange list 0 -1
1) "l3"
2) "l4"
127.0.0.1:6379>
########################################################################
#rpoplpush 从一个list 的最右边的一个值pop出来push进别的list中
127.0.0.1:6379> rpush list 4 5 6
(integer) 6
127.0.0.1:6379> lrange list
(error) ERR wrong number of arguments for 'lrange' command
127.0.0.1:6379> lrange list 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379> rpoplpush list destination
"6"
########################################################################
#linsert 在之前或之后插入
127.0.0.1:6379> linsert list before 3 inserttest #插入在3之前
(integer) 6
127.0.0.1:6379> lrange list 0 -1
1) "value"
2) "2"
3) "inserttest"
4) "3"
5) "4"
6) "5"
127.0.0.1:6379> linsert list after 4 inserttest2 #插入在4之后
(integer) 7
127.0.0.1:6379> lrange list 0 -1
1) "value"
2) "2"
3) "inserttest"
4) "3"
5) "4"
6) "inserttest2"
7) "5"
127.0.0.1:6379>
Set
集合中的值不能重复,set是无需不重复原则
string和list的元素都是value,set中是member
- sadd
- smembers 查看集合的全部值
- sismember 判断是否存在
- scard 查看一共有几个元素
- srem 移除某一个member
- srandmember 随机抽取几个member
- spop 随机删除几个member
- smove 移动member到另一个set,可以适用于共同关注功能实现
- sdiff difference set 差集 ,结果来自first_key为基准
- sinter intersection set 交