Redis

140 阅读12分钟

一.nosql

1.概述

<1>是什么

I.概述

nosql不仅仅是sql,泛指非关系型数据库

II.特点

解耦
i.方便扩展
数据之间没有关系
ii.大数据量高性能
nosql的缓存记录级是一种细粒度的缓存,性能高
iii.数据类型多类型
不需要事先设计数据库
iv.传统RDMBS和Nosql对比

image.png

<2>为什么用

I.单机mysql时代

II.缓存+mysql+垂直拆分(读写分离的技术)

i.mysql+垂直拆分
把一台服务器写mysql拆分成好多台,其中一台负责写,另外几台同步数据过去就可以,使用了读写分离的思想,这样就可以满足在java程序中读数据库的时候,不论从哪台服务器读,数据都是一致的

image.png

ii.缓存+mysql+垂直拆分
添加缓存,让用户a访问到某一台服务器的时候,先把数据放到缓存,下次读到这台服务器的时候就先到缓存找,就可以减轻服务器的压力,提升效率
至于缓存用的什么技术,可以是mycat或其他,就是为了解决读的问题    

image.png

III.分库分表+水平拆分(水平拆分就是mysql集群)

用户先到缓存查数据,查不到到集群查,比如每个集群放置用户的一部分数据,就构成了完整的集群,本质上是解决数据库的读写
Innodb:行锁(解决了写的问题),后来就是分库分表解决写的压力

image.png

IV.最近的年代

目前一个基本的互联网项目

image.png

mysql关系型数据库不够用,因为数据量大,比如文件,博客,图片这种大数据量的文件,用mysql数读效率低,就应该有专门处理这些数据的数据库,nosql出现了;
可以解决比如用户的个人信息,社交网络,地理位置;用户自己产生的数据,用户日志等等爆发性增长的数据

2.阿里巴巴架构的演进

3.nosql的数据模型

4.nosql的四大分类

image.png

<1>键值对存储

KV键值对:
    新浪:redis
    美团:redis+tail
    阿里,百度:redis+memecache

<2>列存储

HBase
分布式文件系统

<3>文档存储(bson格式和json类似)

MongoDB:(是nosql非关系型数据库中功能最丰富,最像关系型数据库的一类)
    基于分布式文件存储的数据库,一般用来处理大量的文档,是由c++编写的;
    它是介于关系型数据库和非关系型数据库中间的产品

<4>图形数据库

不是放图片的,是放关系的

5.CAP与BASE理论

二.Redis

1.是什么

c语言编写的,支持网络(可以通过http协议传输东西),基于内存,支持持久化,key-value型数据库,可用多种语言调用的结构化数据库
是当下最火的nosql技术之一    

image.png

2.用来干什么

可以用作数据库存数据,还可以用做缓存,还可以用作消息中间件mq

<1>内存存储,持久化(rdb,aof)

内存断电即失,所以持久化可以把数据放在本地,也就是数据库关闭之后,数据依旧存在
持久化机制:rdb和aof

<2>效率高,用于高效缓存

<3>发布订阅系统(等同于消息中间件MQ)

可以做一些消息队列的事情

<4>地图信息分析

<5>计时器,计数器

3.redis特性

<1>支持多样的数据类型
<2>支持持久化
<3>支持事务
<4>支持集群

4.怎么用

<1>.基本环境

I.官网

https://redis.io/

II.linux下载安装redis

i.下载安装包

image.png

ii.解压安装包
[root@userAlex /]# cd /home/alex
[root@userAlex alex]# mv redis-6.2.6.tar.gz /opt
[root@userAlex alex]# cd /opt
[root@userAlex opt]# ls
containerd  redis-6.2.6.tar.gz
[root@userAlex opt]# tar -zxvf redis-6.2.6.tar.gz
iii.查看redis的配置文件

image.png

iv.基本环境安装
[root@userAlex redis-6.2.6]# yum install gcc-c++
#执行make,让所有需要的文件进行配置
[root@userAlex redis-6.2.6]#make
[root@userAlex redis-6.2.6]# make install
v.查看redis程序的路径
redis默认安装路径是/usr/local/bin
#所有自己安装的本地程序都在/usr/local/bin目录下
vi.在默认路径下新建一个文件,将redis的配置文件复制到当前目录下
[root@userAlex bin]# mkdir alexredisconfig
[root@userAlex bin]# cp /opt/redis-6.2.6/redis.conf  alexredisconfig/
[root@userAlex bin]# cd alexredisconfig/
[root@userAlex alexredisconfig]# ls
redis.conf
#以后用这个配置文件启动就可以,原生的配置文件就在解压后的文件,不用动,保证安全性
vii.启动
1)配置
默认不是后台启动的,需要修改配置文件    
[root@userAlex alexredisconfig]# vim redis.conf

image.png

2)通过指定的配置文件启动服务
在redis的默认路径下启动
#定义全局命令
#通过指定的配置文件启动服务
#[root@userAlex bin]# redis-server alexredisconfig/redis.conf
[root@userAlex bin]# /usr/local/bin/redis-server /usr/local/bin/alexredisconfig/redis.conf
#使用redis客户端进行连接
#[root@userAlex bin]# redis-cli -p 6379
[root@userAlex bin]# /usr/local/bin/redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> set name alex
OK
127.0.0.1:6379> get name
"alex"
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379>
3)查看redis进程    
[root@userAlex bin]# ps -ef|grep redis
root      2259   864  0 02:26 pts/0    00:00:00 /usr/local/bin/redis-cli -p 6379
root      2886  2847  0 02:31 pts/2    00:00:00 grep --color=auto redis
root     31823     1  0 02:00 ?        00:00:01 ./redis-server *:6379
4)关闭redis服务    
127.0.0.1:6379> shutdown
not connected> exit

III.性能测试

i.是什么
redis-benchmark是一个官方自带的压力测试工具,用来测试redis性能测试
使用一些参数即可        
[root@userAlex bin]# /usr/local/bin/redis-benchmark -h localhost -p 6379 -c 100 -n 100000

image.png

ii.怎么用
测试100个并发连接,每个并发有10w个请求
①.读取请求
②.分析请求

image.png

<2>.redis基础知识与基本数据类型

I.基础知识

i.redis默认有16个数据库
①通过查看配置文件查看redis的默认数据库
[root@userAlex bin]# cat alexredisconfig/redis.conf

image.png

②默认用的是第一个数据库,可以通过select命令切换用的哪个数据库
实例:使用第三个数据库并存数据
命令说明:
    DBSIZE:查看数据库容量大小
    keys * :查看当前数据库所有的key
    flushdb :清空当前数据库的数据
[root@userAlex bin]#  /usr/local/bin/redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]> set name alex
OK
127.0.0.1:6379[3]> DBSIZE
(integer) 1
127.0.0.1:6379[3]> get name
"alex"
127.0.0.1:6379[3]> keys *
1) "name"
127.0.0.1:6379[3]> flushdb
OK
127.0
i.reids是单线程
①redis是基于内存操作的
cpu不是redis的性能瓶颈,他的瓶颈是根据机器的内存和网络带宽,所以不需要使用多线程
②redis为什么这么快
redis是c语言写的,不比memecache差,redis是把数据都放在内存的,所以使用单线程操作,效率就是最高的(cpu会切换上下文耗时,所以对于单线程,没有上下文的切换效率才是高的)
误区:
(1)高性能服务器不一定是多线程的
(2)多线程不一定比单线程效率高

II.五大数据类型与三种特殊数据类型

i.redis五大基本数据类型以及对应的使用场景
①redis-key(redis中关于key的操作)
1)基本命令
    exists key:判断当前数据库是否有key
    move key 1:从当前数据库移除key
    expire key time(s):设置过期时间
        ttl key:查看剩余过期时间
    type:查看当前key的数据类型
(2)expire场景
服务器上用来做缓存,如热点数据让它在一定时间内自动过期;
用户的cookie也可以这么用;
单点登录,设置登录的过期时间
[root@userAlex /]# /usr/local/bin/redis-cli -p 6379
127.0.0.1:6379> ping
PONG
127.0.0.1:6379[3]> set name alex
OK
127.0.0.1:6379[3]> set age 1
OK
127.0.0.1:6379[3]> keys *
1) "age"
2) "name"
127.0.0.1:6379[3]> exists name
(integer) 1
127.0.0.1:6379[3]> move name 1
(integer) 1
127.0.0.1:6379[3]> keys *
1) "age"
127.0.0.1:6379[3]> expire age 10
(integer) 1
127.0.0.1:6379[3]> ttl age
(integer) 6

127.0.0.1:6379[3]> set name alex
OK
127.0.0.1:6379[3]> type name
string
②string
(1)基本命令
    append :追加,如果追加的字符串不存在就会等同于set key value
    strlen:截取字符串长度
    incr:执行i++的操作
    range:截取字符串范围
        getrange
        setrange:更换字符串
    setex/setns : 设置过期时间
    mget/mset:批量获取/设置值
    getset :先get后set

image.png image.png image.png image.png

image.png

image.png

image.png

(2)使用场景
    存放热点数据,计数器,统计多单位的数量,对象缓存存储
    incr:配合网站阅读量的实现
    setex/setnx :用在分布式锁
    
③list(集合)
redis中,list列表实际上是一个链表
redis中,可以把list做成队列,栈,阻塞队列

image.png

(1)基本命令
所有list命令都是l开头的 
push:放元素(可以添加重复值)
pop:移除元素
range/index:获取值/根据下标获取值
len:查看列表长度
rem:移除指定的元素(如移除指定的用户)
trim:获取key但只是获取一部分
poplpush:移除列表最后一个元素并把这个元素添加到其他的列表
set:更新元素
insert:插入值

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

(2)使用场景
    消息排队,消息队列(LPUSH/RPOP),栈(LPUSH/LPOP)
    
④set(无序不重复集合)
set的命令都是以s开头的
(1)基本命令       
    add:添加值(不可以添加重复值)
    members:查看指定set中的所有值
    ismember:判断key存不存在
    card:查看set中的元素个数
    rem:移除set中的元素
    randmember:随机抽取set中的元素
    pop:删除set中的key
    move:把集合中的指定key移动到其他的集合中
    数字集合类
    

image.png

image.png

image.png

image.png

image.png

image.png

image.png

(2)使用场景    

image.png

⑤hash(map集合)
hash存的是key-map(key-map<key,value>),也就是key的值是map集合;
(1)基本命令(都已h开头)
get/set:存值和取值
mget/mset:同时获取/设置多个值    

image.png

image.png

image.png

image.png

image.png

2)使用场景
    更适合对象的存储,string更适合字符串的存储
    存变更数据,比如用户信息的保存,经常变动的信息
    key-map
    user-name,age
    
⑥ Zset(有序集合)
ii.其他三种特殊数据类型
①geospatial
官方文档:http://www.redis.net.cn/order/3685.html
地理位置空间,redis3.2后推出的功能,简称Geo
(1)基本命令 (命令都已Geo开头) 
add:添加位置
dist:获取两个地理位置的距离
hash
pos:获取当前位置
radius
radiusbymember

image.png

image.png

image.png

image.png

image.png

image.png

(2)使用场景
朋友定位,附近的人,打车距离计算
②hyperloglog
数据统计
(1)基本命令

image.png

(2)使用场景
统计不重复的数量
    
③bitmaps
(1)基本命令
(2)使用场景
存位图

<3>.Redis事务操作

如何读取配置文件

I.关系型数据库事务的ACID原则

关系型数据库中的原子性是很重要的,而在非关系型数据库中,如redis的单条命令是保证原子性的,但reids的事务不能保证原子性

II.redis的事务

i.概念
本质就是一组命令的集合,也就是把几条单独执行的命令放进队列中,通过一条命令执行队列里的好多条命令,执行的过程不允许被打断;一个事务中的命令都会被序列化,执行过程中,会按照顺序执行
ii.特性
没有原子性,也没有隔离性(也就是没有隔离级别的概念),但有一次性,顺序性,排他性
iii.命令
multi:开启命令
命令入队
exec:执行命令

image.png

image.png

image.png

image.png

iv.加锁(watch做监控,直接用watch就能加乐观锁)
监控的功能可以用乐观锁实现
①单线程正常执行

image.png

②多线程:第一个线程执行的时候,第二个线程改变了数据
第一个线程开启了事务的命令并执行入队操作,还没有执行事务的时候,另一条线程修改了数据,watch监控就会报错,当事务执行失败,先用unwatch解锁,再用新的乐观锁

image.png

image.png

③使用场景
商品秒杀,就用watch做乐观锁

<4>Jredis

I.是什么

reids官方推荐的java连接开发工具

II.为什么用

需要使用java操作redis,如果要用java操作redis,就必须对Jredis十分熟悉

III.怎么用

i.导入依赖

image.png

ii.打开本地的redis客户端
iii.编码测试
①连接数据库

image.png

②常用API操作测试
参考redis.pdf
③断开连接
iv.使用Jredis操作事务
参考redis.pdf

<4>.redis.config(配置详解)

<5>.Redis持久化

Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以 Redis 提供了持久化功能!

I.RDB

i.是什么

image.png

ii.怎么用
如何触发rdb机制
①配置文件中默认的快照配置,建议多用一台机子作为备份,复制一份 dump.rdb
②命令save或者是bgsave
    save 时只管保存,其他不管,全部阻塞
    bgsave,Redis 会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave 命令获取最后一次成功执行快照的时间。
③执行flushall命令,也会产生 dump.rdb 文件,但里面是空的,无意义 ! 
④退出redis的时候也会产生 dump.rdb 文件!
如何恢复rdb文件
①将备份文件(dump.rdb)移动到redis安装目录并启动服务即可 (redis启动的时候会自动检查dump.rdb恢复其中的数据)
②CONFIG GET dir 获取目录

127.0.0.1:6379> config get dir
dir
/usr/local/bin #在这个目录下存在dump.rdb文件,启动redis就会恢复里面的数据

II.AOF

i.是什么
ii.怎么用

<6>.Redis实现订阅发布(消息队列也是做这个)

<7>.Redis集群相关

I.主从复制

II.Redis哨兵模式(公司的集群现在基本都是这个模式)

<10>.分布式相关(高可用问题)

项目上线以后,出现的问题

I.缓存穿透即解决方案

II.缓存击穿即解决方案

III.缓存雪崩即解决方案

IV.基础API-Jredis

V.springboot集成Redis

<11>.Redis真实使用场景分析