一.nosql
1.概述
<1>是什么
I.概述
nosql不仅仅是sql,泛指非关系型数据库
II.特点
解耦
i.方便扩展
数据之间没有关系
ii.大数据量高性能
nosql的缓存记录级是一种细粒度的缓存,性能高
iii.数据类型多类型
不需要事先设计数据库
iv.传统RDMBS和Nosql对比
<2>为什么用
I.单机mysql时代
II.缓存+mysql+垂直拆分(读写分离的技术)
i.mysql+垂直拆分
把一台服务器写mysql拆分成好多台,其中一台负责写,另外几台同步数据过去就可以,使用了读写分离的思想,这样就可以满足在java程序中读数据库的时候,不论从哪台服务器读,数据都是一致的
ii.缓存+mysql+垂直拆分
添加缓存,让用户a访问到某一台服务器的时候,先把数据放到缓存,下次读到这台服务器的时候就先到缓存找,就可以减轻服务器的压力,提升效率
至于缓存用的什么技术,可以是mycat或其他,就是为了解决读的问题
III.分库分表+水平拆分(水平拆分就是mysql集群)
用户先到缓存查数据,查不到到集群查,比如每个集群放置用户的一部分数据,就构成了完整的集群,本质上是解决数据库的读写
Innodb:行锁(解决了写的问题),后来就是分库分表解决写的压力
IV.最近的年代
目前一个基本的互联网项目
mysql关系型数据库不够用,因为数据量大,比如文件,博客,图片这种大数据量的文件,用mysql数读效率低,就应该有专门处理这些数据的数据库,nosql出现了;
可以解决比如用户的个人信息,社交网络,地理位置;用户自己产生的数据,用户日志等等爆发性增长的数据
2.阿里巴巴架构的演进
3.nosql的数据模型
4.nosql的四大分类
<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技术之一
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.下载安装包
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的配置文件
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
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
ii.怎么用
测试100个并发连接,每个并发有10w个请求
①.读取请求
②.分析请求
<2>.redis基础知识与基本数据类型
I.基础知识
i.redis默认有16个数据库
①通过查看配置文件查看redis的默认数据库
[root@userAlex bin]# cat alexredisconfig/redis.conf
②默认用的是第一个数据库,可以通过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
(2)使用场景
存放热点数据,计数器,统计多单位的数量,对象缓存存储
incr:配合网站阅读量的实现
setex/setnx :用在分布式锁
③list(集合)
redis中,list列表实际上是一个链表
redis中,可以把list做成队列,栈,阻塞队列
(1)基本命令
所有list命令都是l开头的
push:放元素(可以添加重复值)
pop:移除元素
range/index:获取值/根据下标获取值
len:查看列表长度
rem:移除指定的元素(如移除指定的用户)
trim:获取key但只是获取一部分
poplpush:移除列表最后一个元素并把这个元素添加到其他的列表
set:更新元素
insert:插入值
(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移动到其他的集合中
数字集合类
(2)使用场景
⑤hash(map集合)
hash存的是key-map(key-map<key,value>),也就是key的值是map集合;
(1)基本命令(都已h开头)
get/set:存值和取值
mget/mset:同时获取/设置多个值
(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
(2)使用场景
朋友定位,附近的人,打车距离计算
②hyperloglog
数据统计
(1)基本命令
(2)使用场景
统计不重复的数量
③bitmaps
(1)基本命令
(2)使用场景
存位图
<3>.Redis事务操作
如何读取配置文件
I.关系型数据库事务的ACID原则
关系型数据库中的原子性是很重要的,而在非关系型数据库中,如redis的单条命令是保证原子性的,但reids的事务不能保证原子性
II.redis的事务
i.概念
本质就是一组命令的集合,也就是把几条单独执行的命令放进队列中,通过一条命令执行队列里的好多条命令,执行的过程不允许被打断;一个事务中的命令都会被序列化,执行过程中,会按照顺序执行
ii.特性
没有原子性,也没有隔离性(也就是没有隔离级别的概念),但有一次性,顺序性,排他性
iii.命令
multi:开启命令
命令入队
exec:执行命令
iv.加锁(watch做监控,直接用watch就能加乐观锁)
监控的功能可以用乐观锁实现
①单线程正常执行
②多线程:第一个线程执行的时候,第二个线程改变了数据
第一个线程开启了事务的命令并执行入队操作,还没有执行事务的时候,另一条线程修改了数据,watch监控就会报错,当事务执行失败,先用unwatch解锁,再用新的乐观锁
③使用场景
商品秒杀,就用watch做乐观锁
<4>Jredis
I.是什么
reids官方推荐的java连接开发工具
II.为什么用
需要使用java操作redis,如果要用java操作redis,就必须对Jredis十分熟悉
III.怎么用
i.导入依赖
ii.打开本地的redis客户端
iii.编码测试
①连接数据库
②常用API操作测试
参考redis.pdf
③断开连接
iv.使用Jredis操作事务
参考redis.pdf
<4>.redis.config(配置详解)
<5>.Redis持久化
Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以 Redis 提供了持久化功能!
I.RDB
i.是什么
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>.分布式相关(高可用问题)
项目上线以后,出现的问题