NoSql学习笔记
一、入门概述
1.为什么引入NoSQL
- NoSQL:Not Only SQL 泛指非关系型数据库;其数据类型不需要固定的模式,无需多余的操作就可以横向扩展
1.1传统关系型数据库的瓶颈
1.2引入缓存
1.3Mysql主从复制、读写分离
- 主从复制:一条记录可以同时放入主库和从库,增加安全性,防止数据丢失
- 读写分离:读可以在从库进行,写只在主库进行
1.4分表分库+水平拆分+mysql集群
- 分表分库:相关性较高的尽量放到同一个库,以此标准进行分库,提高内聚性;
1.5MySql的扩展性瓶颈
1.6今天是什么样子
1.7为什么使用NoSQL
2.NoSQL的特征
- 【注】:NoSQL的读写速度,大概1秒可以写8万次,读11万次
传统RDBMS VS NoSQL
3.NoSQL的数据库产品
- Redis
- Memcache
- MongoDB
- …
4.关键点
- KV 即Key-Value
- Cache
- Persistence
【注】:面试时问到Redis可以说,关键点是 KV+Cache+Persistence
4.大数据的特征
- 海量Volume
- 多样Variety
- 实时Velocity
5.大数据下互联网的需求
- 高并发
- 高可扩
- 高性能
【注】:高可扩一般意味着横向可扩,即一台机器性能不够,可以多加几台机器,形成集群,通过负载均衡等实现协调,对外表现的就像是一台机器;而相对而言的纵向扩展,即不停地扩展一台机器的性能,但是一台机器的性能总归是有极限的;
6.当下NoSQL的经典应用
-
阿里中文网站商品信息存放方式
- 当下的应用是 SQL 和 NoSQL 一起使用
- 不怎么变化的,趋冷的数据,存放到关系型数据库里(阿里用的Mysql,但阿里用的mysql是经过阿里改造过的)
- 文档类数据(如评论)存放在MongoDB
- 图片存储在分布式的存储系统中,如Hadoop的HDFS
- 商品的搜索关键字存放在ISearch
- 热点高频词汇 tair、Redis、Memcache
- 商品的交易、价格计算、积分累积存放在支付宝、外部的第三方支付接口
-
鉴于使用了多种类型的数据库来存储各种数据,如果每种数据库都要单独操作,则比较繁琐,所以阿里在各种数据库之上做了一层封装(统一数据平台服务层,UDSL),类似于JDBC在Oracle、mysql之上做了封装,使得可以通过一种统一的方式访问多种数据库
7.NoSQL如何设计
7.1 KV键值对
7.2 BOSN
- Binary JSON 即二进制的JSON,类似于JSON,NoSQL中可以用BSON来描述数据对象,如MongoDB就使用的BSON
- 易扩展性
7.3 列族
- 将各列直接连接主键,以类似键值对的方式
7.4 图形
关于关联查询
- 许多场景下是尽量避免关联查询的,如分布式场景下,不同的表可能存放在不同的机器,关联查询的效率就变差了
8.NoSQL数据库的分类
9.CAP+BASE
CAP
- CAP是针对传统关系型数据库的ACID
- CAP分别是Consistency(一致性), Availability(可用性),Partition tolerance(分区容错性、分布式容忍性)
【注】:NoSQL中CAP最多只能较好的满足两个,如CA,CP,AP(用的比较多的,即弱一致性,高可用性,分布式容忍性)
BASE
Basically Available(基本可用), Soft State(软状态),Eventually consistent(最终一致性)
- 【注】:用某一时刻的实时的数据一致性来换取系统的可用性和性能;而一致性可以放宽时间的要求,只求最终一致性;
10.分布式 和 集群
二、Redis
1.简介
- Redis:Remote Dictionary Server (远程字典服务器)
- 开源免费、C语言编写、遵守BSD协议,高性能的(Key/Value)分布式内存数据库
- 支持数据的持久化,可以将内存中的数据保存到磁盘中,重启时可以再次加载进行使用
- 事务的控制:Redis可能部分commit,比如三条消息可能提交两条,放弃一条,而关系型数据库要么三条全成,要么全不成
2.下载安装
-
直接官网下载、解压即可
-
make+make install命令安装
$ cd redis-6.2.1
$ make
$ make install
# 如果make命令not found,则需要先下载GCC(C的编译器)
# 默认安装目录为 /usr/local/bin/
$ sudo cp redis.conf /etc/
$ vim redis.conf
# 修改 daemonize yes ,表示可以作为后台程序运行
3.运行Redis
$ redis-server /etc/redis.conf # 使用修改过的配置文件启动 redis-server
$ redis-cli -p 6379 # 连接redis,默认端口 6379
127.0.0.1:6379> ping # 测试是否连接成功
PONG # PONG 表示成功
127.0.0.1:6379> set k1 hello # 插入数据 key—value 形式,重复定义时,k1会被覆盖
OK
127.0.0.1:6379> get k1 # 获取数据
"hello"
127.0.0.1:6379> shutdown # 关闭redis-server
# CTRl+C退出redis命令行
$ ps -ef | grep redis # 查看redis相关进程
$ kill -9 85136 # 通过PID,kill进程(除了上面shutdown之外,关闭redis的另一种方式)
4.Redis命令解析
$ redis-benchmark # 查看redis读写速度,官方的要求是 写8w/秒,读11w/秒
127.0.0.1:6379> select 7 # 切换成第8个数据库(数据库从0开始编号)
127.0.0.1:6379> dbsize # 查看当前数据库的key的数量
127.0.0.1:6379> keys * # 查看所有的key,类似关系库的select *
127.0.0.1:6379> keys k1 # 查找名字为k1的key
127.0.0.1:6379> keys k? # 支持通配符,如 *、?
127.0.0.1:6379> FLUSHDB # 清空当前库
127.0.0.1:6379> FLUSHALL # 清空所有16个库
127.0.0.1:6379> EXISTS k1 # 存在返回1,不存在返回0
127.0.0.1:6379> move k1 2 # 将k1移动到2号库
127.0.0.1:6379> ttl k1 # tt1即 time to leave k1的存活时间,秒数为单位,-1代表永久存留,-2表示已过期
127.0.0.1:6379> EXPIRE k3 10 # 设置k3的生命周期为10秒,时间已过,k3就被移出内存
127.0.0.1:6379> DEL k3 # 删除 k3
127.0.0.1:6379> type k1 # 查看 k1 的类型
127.0.0.1:6379> lpush mylist 1 2 3 4 5 # 插入一个list
127.0.0.1:6379> LRANGE mylist 0 -1 # 查看list中的元入
127.0.0.1:6379> save # 手动备份到dump.rdb
- 【注】:16个数据库(一起工作,以提高效率),端口号等都是在 redis.conf 中配好的
5.Redis的数据类型
三、解析配置文件
1.注意点
- 修改配置文件之前,记得做好备份
2.Include
################################## INCLUDES ###################################
# Include one or more other config files here.
# The format can be as below,
# and if there are more than one .conf files,the configuration of below files will override these above files
# include /path/to/local.conf
3.Networok
################################## NETWORK #####################################
# 配置网络相关的内容,接受哪些ip地址的请求,tcp-backlog, timeout,tcp-keepalive等
4.General
################################# GENERAL #####################################
# 配置通用配置,如loglevel,logfile,databases数量等
5.Snapshotting
################################ SNAPSHOTTING ################################
6.Security
################################## SECURITY ###################################
# Redis默认不设置密码,手动设置方法如下
config get requirepass "123456" # 设置redis的密码
# 设置完成密码后,访问redis需要
127.0.0.1:6379> AUTH 123456
7.Memory Management
############################## MEMORY MANAGEMENT ################################
# redis会使用到 LRU(Least Recently Used) 作为优化内存的策略
8.常见redis.conf介绍
四、Redis的持久化
1.什么是Redis的持久化
- rdb
- aof
2.RDB
- redis database
- 将内存中的snapshot写入到磁盘(以文件的形式dump.rdb)
- 注意,持久化的操作是由子线程完成的,所以并不影响主线程的效率
127.0.0.1:6379> save # 手动备份到dump.rdb
3.AOF
-
append only file
-
以日志的形式记录每个写操作,将数据库写操作备份到 aof 文件中,如果产生数据丢失(最后一次时间间隔,内存的snapshot未备份),则可以通过aof文件中的操作进行数据恢复
-
具体做法: 首先要修改配置文件
- 如果同时存在 appendonly.aof 和 dump.rdb 同时存在,先加载的是.aof
- 如果.aof文件出现问题了,可以修复
127.0.0.1:6379> redis-check-aof --fix appendonly.aof
- aof文件会持续增长变大,当过大时,会自动精简,执行压缩算法
五、Redis的一致性
- 方案1:在数据库中做增删改的同时,也在Redis中做同样的操作
- 方案2:定时删库,清除Redis中的数据,然后重新导入数据
六、Redis的事务
1.是什么
- 一次执行多个命令,本质是一组命令的集合
2.Redis常用命令
3.悲观锁 & 乐观锁
- 悲观锁:默认认为会出现冲突,则先加锁在进行操作
- 乐观锁:默认其他记录不会出现问题,先操作,出问题了报错,让用户决定怎么处理
七、消息订阅发布
127.0.0.1:6379> SUBSCRIBE c1 c2 c3 # 订阅频道c1 c2 c3
127.0.0.1:6379> PUBLISH c2 hello-redis # 在c2频道发布消息hello-redis
八、主从复制,读写分离
1.怎么做
- 配从不配主
- redis.conf 的名字也要改,以区分不同的server
# 首先,通过三个配置文件分别启动三个redis-server
# Slave 配置
SLAVEOF 127.0.0.1 6379 # 表明认127.0.0.1 6379为master,以进行备份,主机中的所有数据都会被备份到从机
SLAVEOF no one # 删除之前的主从关系,不再做slave
info replication # 查看主从关系
2.注意点
- 从写入不了,只能主来写
- 主机如果出故障,从机会保持slave的身份,原地待命
- 从机如果重启,会失去slave身份,需要与master重新连接才能再次变成slave
- Master/Slave : 主用来写,从用来读
- 读写分离,容灾恢复
3.链式关系
- 可以通过多次 slaveof ,实现树形的层级关系
4.哨兵模式
- 哨兵模式下,主机shutdown后,哨兵会再slave中选出新的主机最为master
- 哨兵一般只监视master
- 哨兵模式下,之前的master如果shutdown之后再重启,会被哨兵指派成slave