简介
关系数据库与非关系型数据库
关系型数据库
- 一个结构化的数据库,创建在关系模型基础上
- 一般面向于记录
包括:Oracle MySQL、SQL Server、Microsoft Access、DB2等
非关系型数据库
- 除了主流的关系型数据库外的数据库,都认为是非关系型
- 包括:Redis、 MongBD、Hbase、CouhDB等
时间序列型数据库
- 非关系数据库中加入了时间轴概念
非关系型数据库产生背景
- High performance——对数据库高并发读写需求
- Huge Storage—对海量数据高效存储与访问需求
- High Scalability && High Availability————对数据库高可扩展性与高可用性需求
Redis
Redis简介
- Redis基于内存运行并支持持久化
- 采用key-value(键值对)的存储形式
- 优点
- 具有极高的数据读写速度
- 支持丰富的数据类型
- 支持数据的持久化
- 原子性
- 支持数据备份
Redis五种数据类型
string
- string是redis最基本的类型,与Memcached一模一样的类型,一个key对应一个value。
- string类型是二进制安全的。redis的string 可以包含任何数据。比如jpg图片或者序列化的对象。
- string 类型是Redis最基本的数据类型,string 类型的值最大能存储512MB。
hash
- Redis hash是一个键值(key=>value)对集合。
- Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
- 每个hash可以存储2的32次方-1键值对。
作用场景:
健值对集合,即编程语言中的Map类型
适合存储对象,并且可以像数据库中update一个属性一样只修改某一项属性值
list
- Redis列表是简单的字符串列表,按照插入顺序排序,可以重复。可以添加一个元素到 表的头部(左边)或者尾部(右边)
- 列表最多可存储2^32 -1 个元素。
作用场景:
1、增删快,提供了操作某一段元素的API
2、最新消息排行等功能(比如朋友圈的时间线)
3、消息队列
一个key写入多个value时,遵循着先入后出,后入先出的堆栈规则
存入的value可以重复
set
- Redis的 Set 是 string 类型的无序集合。
- 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是0(1)
作用场景:
- 比如QQ的共同好友
- 利用唯一性,统计访问网站的所有独立ip
- 好友推荐时,根据tag求交集,大于某个阈值就可以推荐
集合存储,不论有序还是无序都不能存储重复的值
zset
- Redis zset和set一样也是string类型元素的集合,且不允许重复的成员。
- 不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
作用场景: - 将Set中的元素增加一个权重参数score,元素按score有序排列
数据插入集合时,已经进行天然排序
- 排行榜
- 带权重的消息队列
Redis部署流程
[root@server1 ~] yum -y install gcc gcc-c++ make 安装编译安装的依赖包
[root@server1 ~] tar zxf redis-5.0.7.tar.gz 解压软件包
[root@server1 ~] cd redis-5.0.7/ 进入软件包(注意此时安装包在/opt目录下 后续命令的路径会有所不同)
[root@server1 redis-5.0.7] make 编译安装
[root@server1 redis-5.0.7] make PREFIX=/usr/local/redis install dizhidin 指定安装的目录
[root@server1 redis-5.0.7] ln -s /usr/local/redis/bin/* /usr/local/bin
[root@server1 redis-5.0.7] cd utils/
[root@server1 utils] ./install_server.sh 安装后redis就自动开启了
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379] 默认端口
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf] 配置文件路径
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log] 日志文件路径
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379] 数据文件路径
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server] 执行文件路径
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf
Log file : /var/log/redis_6379.log
Data dir : /var/lib/redis/6379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli 客户端命令工具
Is this ok? Then press ENTER to go on or Ctrl-C to abort. 看到这个回车 确认一下上面的各路径
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
[root@server1 utils] vi /etc/redis/6379.conf
bind 127.0.0.1 20.0.0.10 把允许登录的地址bind后面
[root@server1 utils] /etc/init.d/redis_6379 restart
[root@server1 utils] netstat -lutap | grep 6379
tcp 0 0 server1:6379 0.0.0.0:* LISTEN 63156/redis-server
tcp 0 0 localhost:6379 0.0.0.0:* LISTEN 63156/redis-server
[root@server1 utils] redis-cli -h 20.0.0.10 -p 6379 远程连接数据库
20.0.0.10:6379>
[root@server1 utils] redis-cli 本地连接
127.0.0.1:6379>
Redis配置文件
配置参数(/etc/redis/6379.conf)
- bind:监听的主机地址
- port:端口
- daemonize yes:启用守护进程
- pidfile:指定PID文件
- loglevel notice:日志级别.
- logfile:指定日志文件
Redis数据库常用命令
redis-cli命令行工具
- 连接本地数据库
[root@localhost utils] /usr/local/redis/bin/redis-cli 127.0.0.1:6379
- 连接远程数据库
[root@localhost utils]# redis-cli -h 192.168.10.161 -p 6379 -c
获取命令帮助
- help @:获取中的命令列表
- help :获取某个命令的帮助
- help :获取可能帮助的主题列表
基础操作命令
- set:存放数据
- get:获取数据
[root@localhost ~]#/usr/local/redis/bin/redis-cli
20.0.0.10:6379> set teacher zhanglong
OK
20.0.0.10:6379> get teacher
"zhanglong"
key相关命令
格式:[选项] 参数
- keys:获取符合规则的键值列表
示列:
20.0.0.10:6379> keys nam?
1) "name"
20.0.0.10:6379> keys na??
1) "name"
- exists:判断键值是否存在
示列:
20.0.0.10:6379> exists name
(integer) 1 #执行失败返回0,执行成功返回非0值
- del:删除当前数据库的指定key
示列:
20.0.0.10:6379> keys *
1) "name"
2) "age"
20.0.0.10:6379> del age
(integer) 1
20.0.0.10:6379> keys *
1) "name"
- type:获取key对应的value值类型
示列:
20.0.0.10:6379> type name
string
- rename(覆盖)l renamenx(不覆盖):对已有的key进行重命名
示列:
20.0.0.10:6379> rename name mingzi
OK
- dbsize:查看当前数据库中key的数目
示列:
20.0.0.10:6379> dbsize
(integer) 1
redis-benchmark测试工具
- -h: 指定服务器主机名
- -p: 指定服务器端口
- -c: 指定并发连接数
- -n: 指定请求数
- -d: 以字节的形式指定SET/GET值的数据大小
- -q: 强制退出Redis,仅显示query/sec值
redis-benchmark压力测试工具
- 向IP地址为192.168.73.10、端口为6379的Redis服务器发送100个并发连接与10000个请求测试性能
[root@server1 ~]# redis-benchmark -h 20.0.0.10 -p 6379 -c 100 -n 10000
- 测试存取大小为100字节的数据包的性能
[root@server1 ~]# redis-benchmark -h 20.0.0.10 -p 6379 -q -d 100
Redis多数库操作
- Redis支持多数据库,默认支持16个数据库,0-15命名,
- 多数据库相互独立,互不干扰
- 多数据库常用命令
- 多数据库间切换
- 多数据库间移动数据
- 清除数据库内数据
127.0.0.1:6379> select 5 #选择数据库5
OK
127.0.0.1:6379[5]> set age 5 #创建键名age,值5
OK
127.0.0.1:6379[5]> keys *
1) "age"
127.0.0.1:6379[5]> move age 1 #移动键值到数据库1
(integer) 1
127.0.0.1:6379[5]> select 1
OK
127.0.0.1:6379[1]> keys *
1) "age"
Redis支持存对象
例如:对象是abc
127.0.0.1:6379> hset abc name lisi
(integer) 1
127.0.0.1:6379> hset abc age 18
(integer) 1
127.0.0.1:6379> hset abc score 90
(integer) 1
127.0.0.1:6379> keys *
- “abc”
127.0.0.1:6379> hget abc name
“lisi”
127.0.0.1:6379> hget abc age
“18”
Redis持久化
- 持久化概述
Redis是运行在内存中,内存中的数据断电丢失
为了能够重用Redis数据,或者防止系统故障,需要将Redis中的数据写入到磁盘空间中,即持久化 - 持久化分类
- RDB方式:创建快照的方式获取某一时刻Redis中所有数据的副本
(缺点:只能是一个时刻,不可以连续,存在盲区,可能导致少量数据丢失) - AOF方式:将执行的写命令写到文件的末尾,以日志的方式来记录数据的变化
(缺点:日志文件的量多,人力成本大)
**注意:**生产环境RDB+AOF方式,两个快照中间部分采用AOF方式,查找日志中对应时间的写命令
RDB持久化
- Redis默认的持久化方式
- 默认文件名为dump.rdb
powershell
[root@server1 ~]# cd /var/lib/redis/6379/
[root@server1 6379]# ll
总用量 232
-rw-r--r--. 1 root root 233881 11月 10 14:59 dump.rdb
- 触发条件
在指定的时间间隔内,执行指定次数的写操作(配置文件控制)
执行save或者是bgsave(异步)命令
执行flushall命令,清空数据库所有数据
执行shutdown命令,保证服务器正常关闭且不丢失任何数据 - 优缺点
适合大规模的数据恢复
如果业务对数据完整性和一致性要求不高,RDB是很好的选择
数据的完整性和一致性不高
备份时占用内存 - 通过RDB文件恢复数据
将dump.rdb文件拷贝到redis的安装目录的bin目录下,重启redis服务即可
[root@server1 ~]# vim /etc/redis/6379.conf
save 900 1 #900秒之内至少一次写操作
save 300 10 #300秒内至少10次操作
save 60 10000 #60秒内至少10000次写操作
#只要满足其一都会触发快照操作,注释所有的save项表示关闭RDB
dbfilename dump.rdb #RDB文件名称
dir /var/lib/redis/6379 #RDB文件路径
rdbcompression yes #是否进行压缩
AOF持久化
1、Redis默认不开启
2、弥补RDB的不足(数据的不一致性)
3、采用日志的形式来记录每个写操作,并追加到文件中
4、Redis重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
5、根据AOF文件恢复数据
将appendonly.aof文件拷贝到redis安装目录的bin目录下,重启redis服务即可
6、配置文件选项
[root@server1 ~]# vim /etc/redis/6379.conf
appendonly yes #开启AOF持久化
appendfilename “appendonly.aof” #AOF文件名称
#appendfsync always #同步持久化,每次发生数据变化会立刻写入磁盘;
appendfsync everysec #默认推荐,每秒异步记录一次(默认值)
#appendfsync no #不同步,交给操作系统决定如何同步
aof-load-truncated yes #忽略最后一条可能存在问题的指令
- AOF的重写机制
AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多
当AOF文件的大小超过所设定的阀值时,Redis就会对AOF文件的内容压缩 - AOF的重写的原理
Redis会fork出一条新进程,读取内存中的数据(并没有读取旧文件),并重新写到一个临时文件中,最后替换旧的aof文件 - AOF的重写配置
[root@redis 6379]# vim /etc/redis/6379.conf
no-appendfsync-on-rewrite no #在日志进行BGREWRITEAOF时, 如果设置为yes表示新写操作不进行同步fsync,只暂存在缓冲区里,避免造成磁盘I0操作冲突,等重写完成后在写入。redis中默认为no
auto-aof-rewrite-percentage 100 #当前AOF文件大小是上次日志重写时AOF文件大小两倍时,发生BGREWRITEAOF操作
auto-aof-rewrite-min-size 64mb #当前AOF文件执行BGREWRITEAOF命令的最小值,避免刚开始启动Reids时由于文件尺寸较小导致频繁的BGREWRITEAOF.当AOF文件到达64M的时候,发生BGREWRITEAOF操作
如何查看Redis内存使用
[rootmaster1~]# /usr/local/redis/bin/redis-cli127.0.0.1:6379> info memory
Memory
used_memory:2650536 **内存使用总量**
used_memory_human:2.53M
used_memory_rss:12120064
used_memory_rss human:11.56M
used_memory_peak:2650536
used_memory_peak_human:2.53M
used_memory_peak_perc: 100.00%
used_memory_overhead:2573336
used_memory_startup:1458272
used_memory_dataset:77200
used_memory_dataset_perc:6.48%
total_system_memory:1912078336
total_system_memory_human:1.78G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:OB
maxmemory-policy:noeviction
mem_fragmentation_ratio:4.57 **内存碎片率**
mem_allocator:jemalloc-4.0.3
active_defrag_running:0
lazyfree_pending_objects:0
内存碎片率
- 操系统分配的内存值used_memory_rss除以Redis使用的内存值used_memory计算得出
- 内存碎片是由操作系统低效的分配/回收物理内存导致的
◆不连续的物理内存分配 - 跟踪内存碎片率对理解Redis实例的资源性能是非常重要的
◆内存碎片率稍大于1是合理的,这个值表示内存碎片率比较低
◆内存碎片率超过1.5,说明Redis消耗了实际需要物理内存的150%,其中50%是内存碎片率
◆内存碎片率低于1的,说明Redis内存分配超出了物理内存,操作系统正在进行内存交换
内存使用率
- redis实例的内存使用率超过可用最大内存,操作系统将开始进行内存与swap空间交换
- 避免内存交换
◆针对缓存数据大小选择
◆尽可能的使用Hash数据结构
◆设置key的过期时间
回收key
- 保证合理分配redis有限的内存资源
- 当达到设置的最大伐自时,需远牛一个TnyH
◆默认情况下回收策略是禁止删除
◆redis.conf配置文件中修改maxmemory-policy属性值
- volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据.
- volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰.
- volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰
- allkeys-lru:使用LRU算法从所有数据集合中淘汰数据
- allkeys-random:从数据集合中任意选择数据淘汰
- no-enviction:禁止淘汰数据