关系型数据库与非关系型数据库
关系型数据库:
一个机构化的数据库, 创建在关系模型基础上, 一般面向于记录
包括 oracle,MySQL,sqlserver,db2
非关系型数据库:
除了主流的关系型数据库意外的数据库, 都人为是非关系型的
包括 Redis,mongdb,hbase,couhdb
非关系型数据库产生背景
对数据库高并发读写需求
对海量数据高效存储与访问需求
对数据库高可扩展性与高可用需求
Redis 简介
Redis 基于内存运行并支持持久化
采用 key-value(键值对) 的存储形式
优点:
具有极高的数据读写速度
支持丰富的数据类型
支持数据的持久化
原子性
支持数据备份
安装与配置 Redis
1, 安装必要的环境组件, 并安装 Redis
- [[email protected] ~]# yum install gcc gcc-c++ make -y ## 安装环境组件
- [[email protected] ~]# mkdir /mnt/tools
- [[email protected] ~]# mount.cifs //192.168.100.100/tools /mnt/tools/ ## 挂载
- Password for [email protected]//192.168.100.100/tools:
- [[email protected] ~]# cd /mnt/tools/Redis/
- [[email protected] Redis]# ls
- Redis-5.0.7.tar.gz
- [[email protected] Redis]# tar xf Redis-5.0.7.tar.gz -C /opt/ ## 解压
- [[email protected] Redis]# cd /opt/
- [[email protected] opt]# ls
- Redis-5.0.7 rh
- [[email protected] opt]# cd Redis-5.0.7/
- [[email protected] Redis-5.0.7]# make #编译
- ..........// 省略过程
- [[email protected] Redis-5.0.7]# make PREFIX=/usr/local/Redis/ install ## 安装
- ..........// 省略过程
2, 执行配置 Redis 配置文件脚本, 并进行配置
- [[email protected] Redis-5.0.7]# cd utils/
- [[email protected] utils]# ./install_server.sh ## 执行脚本进行配置
- 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/Redis/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/Redis/bin/Redis-server
- Cli Executable : /usr/local/Redis/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!
- [[email protected] utils]# ln -s /usr/local/Redis/bin/*/usr/local/bin/ ## 便于系统识别
- [[email protected] utils]# netstat -ntap | grep 6379 ## 查看监听端口
- tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 18004/Redis-server
- [[email protected] utils]# /etc/init.d/redis_6379 stop ## 关闭 Redis
- Stopping ...
- Redis stopped
- [[email protected] utils]# netstat -ntap | grep 6379 ## 查看监听端口
- tcp 0 0 127.0.0.1:6379 127.0.0.1:33970 TIME_WAIT -
- [[email protected] utils]# /etc/init.d/redis_6379 start ## 开启 Redis
- Starting Redis server...
- [[email protected] utils]# netstat -ntap | grep 6379
- tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 18091/Redis-server
- tcp 0 0 127.0.0.1:6379 127.0.0.1:33970 TIME_WAIT -
- [[email protected] utils]#
- [[email protected] utils]# VIM /etc/Redis/6379.conf ## 修改配置文件
- bind 127.0.0.1 192.168.52.149 ## 设置监听地址
- [[email protected] utils]# /etc/init.d/redis_6379 restart ## 重启 Redis 服务
- Stopping ...
- Redis stopped
- Starting Redis server...
- ###Redis 数据库基础操作
- [[email protected] utils]# Redis-cli -h 192.168.52.149 -p 6379 ## 登录 Redis
- 192.168.52.149:6379> help @list ## 获取帮助列表
- BLPOP key [key ...] timeout
- summary: Remove and get the first element in a list, or block until one is available
- since: 2.0.0
- ...............................// 省略部分内容
- RPUSHX key value
- summary: Append a value to a list, only if the list exists
- since: 2.2.0
- 192.168.52.149:6379> help set ##help 帮助
- SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
- summary: Set the string value of a key
- since: 1.0.0
- group: string
- 192.168.52.149:6379> set name zhangsan ## 设置键值对
- OK
- 192.168.52.149:6379> set.NET www
- OK
- 192.168.52.149:6379> KEYS * ## 查看所有的键
- 1) "name"
- 2) "net"
- 192.168.52.149:6379> KEYS n?? ## 查看键是 n 开头后面是两个字符的
- 1) "net"
- 192.168.52.149:6379> KEYS n* ## 查看键是 n 开头的
- 1) "name"
- 2) "net"
- 192.168.52.149:6379> GET.NET ## 查看键的值
- "www"
- 192.168.52.149:6379> EXISTS.NET ## 查看键是否存在
- (integer) 1 ##1 是存在, 0 是不存在
- 192.168.52.149:6379> EXISTS nat
- (integer) 0
- 192.168.52.149:6379> del.NET ## 删除键
- (integer) 1
- 192.168.52.149:6379> KEYS *
- 1) "name"
- 192.168.52.149:6379> type name ## 查看键的类型
- string
- 192.168.52.149:6379> rename name n1 ## 给键重命名
- OK
- 192.168.52.149:6379> KEYS *
- 1) "n1"
- 192.168.52.149:6379> get n1
- "zhangsan"
- 192.168.52.149:6379> hset person score 80 ## 用 hash 方式建立键值对
- (integer) 1
- 192.168.52.149:6379> hset person name zhangsan ## 用 hash 方式建立键值对
- (integer) 1
- 192.168.52.149:6379> hset person age 30 ## 用 hash 方式建立键值对
- (integer) 1
- 192.168.52.1490:6379> KEYS *
- 1) "person"
- 192.168.52.149:6379> hget person name ## 获取键的值
- "zhangsan"
- 192.168.52.149:6379> hget person age ## 获取键的值
- "30"
- 192.168.52.149:6379> set name lisi ## 获取键的值
- OK
- 192.168.52.149:6379> KEYS *
- 1) "name"
- 2) "person"
- 192.168.52.149:6379> EXPIRE name 10 ## 设置键的自动删除时间 10s
- (integer) 1
- 192.168.52.149:6379> KEYS * ##10s 内查看所有键
- 1) "name"
- 2) "person"
- 192.168.52.149:6379> KEYS * ##10s 后查看所有键
- 1) "person"
- 192.168.52.149:6379> exit ## 退出
3, 进行压测
- [[email protected] utils]# Redis-benchmark -h 192.168.52.149 -p 6379 -c 100 -n 100000
- ## 并发 100,100000 个请求
- ====== SET ======
- 100000 requests completed in 1.14 seconds ## 请求花费的时间
- 100 parallel clients
- 3 bytes payload
- keep alive: 1
- 84.66% <= 1 milliseconds
- 98.48% <= 2 milliseconds
- 99.69% <= 3 milliseconds
- 99.90% <= 18 milliseconds
- 100.00% <= 18 milliseconds
- 87642.41 requests per second
- ====== GET ======
- 100000 requests completed in 1.13 seconds
- 100 parallel clients
- 3 bytes payload
- keep alive: 1
- [[email protected] utils]# Redis-benchmark -h 192.168.52.149 -p 6379 -q -d 100
- ## 以字节形式指定 set/get 值的数据大小
- SET: 90497.73 requests per second
- GET: 90991.81 requests per second
4, 移动键值对到其他的库中 (一共 16 个库)
- [[email protected] utils]# Redis-cli -h 192.168.52.149 -p 6379 ## 进入 Redis
- 192.168.52.149:6379> KEYS *
- 1) "mylist"
- 2) "counter:__rand_int__"
- 3) "n1"
- 4) "key:__rand_int__"
- 5) "myset:__rand_int__"
- 192.168.52.149:6379> SELECT 10 ## 进入第 11 个库
- OK
- 192.168.52.149:6379[10]> KEYS *
- (empty list or set)
- 192.168.52.149:6379[10]> SELECT 0 ## 进入第 1 个库
- OK
- 192.168.52.149:6379> MOVE n1 10 ## 移动键值对到第 11 个库
- (integer) 1
- 192.168.52.149:6379> KEYS *
- 1) "mylist"
- 2) "counter:__rand_int__"
- 3) "key:__rand_int__"
- 4) "myset:__rand_int__"
- 192.168.52.149:6379> SELECT 10 ## 进入第 11 个库
- OK
- 192.168.52.149:6379[10]> KEYS * ## 查看键
- 1) "n1"
- 192.168.52.149:6379[10]> GET n1
- "zhangsan"
- 192.168.52.149:6379[10]> FLUSHDB ## 清除库中数据
- OK
- 192.168.52.149:6379[10]> KEYS * ## 查看所有键
- (empty list or set)
- 192.168.52.149:6379[10]> SELECT 0 ## 切换到第一个库
- OK
- 192.168.52.149:6379>KEYS * ## 查看所有的键
- 1) "myset:__rand_int__"
- 2) "mylist"
- 3) "key:__rand_int__"
- 4) "counter:__rand_int__"
- 192.168.52.149:6379> exit
- [[email protected] utils]#
Redis 持久化
Redis 是运行在内存中, 内存中的数据断电丢失
为了能后重用 Redis 数据, 或者防止系统故障, 我们需要将 Redis 中的数据写入到磁盘空间中, 即持久化
持久化分类
RDB 方式: 创建快照的方式获取某一时刻 Redis 中所有数据的副本
AOF 方式: 将执行的写命令写到文件的末尾, 以日志的方式来记录数据的变化
RDB 持久化
Redis 的默认持久化方式
默认文件名 dump.rdb
触发条件:
在指定的时间间隔内, 执行指定次数的写操作 (配置文件控制)
执行 save 或者是 bgsave(异步) 命令
执行 flushall 命令, 清空数据库所有数据
执行 shutdown 命令, 保证服务器正常关闭且不丢失任何数据
优缺点:
适合大规模的数据恢复
如果业务对数据完整性和一致性要求不高, RDB 是很好的选择
数据的完整性和一致性不高
备份时占用内存
通过 RDB 文件恢复数据
将 dump.rdb 文件拷贝到 Redis 的安装目录的 bin 目录下, 重启 Redis 服务即可
配置 RDB 持久化
- [[email protected] utils]# VIM /etc/Redis/6379.conf
- #900 秒之内至少一次写操作
- save 900 1
- #300 秒之内至少发生 10 次写操作
- save 300 10
- #60 秒之内发生至少 10000 次写操作
- save 60 10000
- # 只要满足其一都会触发快照操作, 注释所有的 save 项表示关闭 RDB
- #RDB 文件名称
- dbfilename dump.rdb
- #RDB 文件路径
- dir /var/lib/Redis/6379
- # 开启压缩功能
- rdbcompression yes
AOF 持久化
Redis 默认不开启
弥补 RDB 的不足 (数据的不一致性)
采用日志的形式来记录每个写操作, 并追加到文件中
Redis 重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
根据 AOF 文件恢复数据
将 appendonly.aof 文件拷贝到 Redis 安装目录的 bin 目录下, 重启 Redis 服务即可
AOF 持久化配置
- [[email protected] utils]# VIM /etc/Redis/6379.conf
- # 开启 AOF 持久化
- appendonly yes
- #AOF 文件名称
- appendfilename "appendonly.aof"
- #always: 同步持久化, 每次发生数据变化会立刻写入磁盘
- # appendfsync always
- #everysec: 默认推荐, 每秒异步记录次 (默认值)
- appendfsync everysec
- #no: 不同步, 交给操作系统决定如何同步
- # appendfsync no
- # 忽略最后一条可能存在问题的指令
- aof-load-truncated yes
AOF 的重写机制
AOF 的工作原理是将写操作追加到文件中, 文件的冗余内容会越来越多
当 AOF 文件的大小超过所设定的阀值时, Redis 就会对 AOF 文件的内容压缩
AOF 重写的原理
Redis 会 fork 出一条新进程, 读取内存中的数据 (并没有读取旧文件), 并重新写到一个临时文件中, 最后替换旧的 aof 文件
AOF 重写配置
- [[email protected] utils]# VIM /etc/Redis/6379.conf
- # 在日志进行 BGREWRITEAOF 时, 如果设置为 yes 表示新写操作不进行同步 fsync,
- # 只暂存在缓冲区里, 避免造成磁盘 I0 操作冲突, 等重写完成后在写入. Redis 中默认为 no
- no-appendfsync-on-rewrite no
- # 当前 AOF 文件大小是上次日志重写时 AOF 文件大小两倍时, 发生 BGREWRITEAOF 操作
- auto-aof-rewrite-percentage 100
- # 当前 AOF 文件执行 BGREWRITEAOF 命令的最小值,
- # 避免刚开始启动 Reids 时由于文件尺寸较小导致频繁的 BGREWRITEAOF
- auto-aof-rewrite-min-size 64mb
Redis 性能管理
- ## 查看 Redis 内存使用
- [[email protected] utils]# /usr/local/Redis/bin/Redis-cli
- 127.0.0.1:6379> info memory
内存碎片率
●操系统分配的内存值 used_ memory rss 除以 Redis 使用的内存值
used _memory 计算得出
●内存碎片是由操作系统低效的分配 / 回收物理内存导致的
不连续的物理内存分配
●跟踪内存碎片率对理解 Redis 实例的资源性能是非常重要的
内存碎片率稍大于 1 是合理的, 这个值表示内存碎片率比较低
内存碎片率超过 1.5, 说明 Redis 消耗了实际需要物理内存的 150%, 其中 50% 是内存碎片率
内存碎片率低于 1 的, 说明 Redis 内存分配超出了物理内存, 操作系统正在进行内存交换
内存使用率
●Redis 实例的内存使用率超过可用最大内存, 操作系统将开始进行
内存与 swap 空间交换
●避免内存交换
针对缓存数据大小选择
尽可能的使用 Hash 数据结构
设置 key 的过期时间
回收 key
●保证合理分配 Redis 有限的内存资源
●当内存使用达到设置的最大阀值时, 需要选择一种 key 的回收策略
默认情况下回收策略是禁止删除
Redis.conf 配置文件中修改 maxmemory-policy 属性值
volatile-lru: 使用 LRU 算法从已设置过期时间的数据集合中淘汰数据
volatile-ttl: 从已设置过期时间的数据集合中挑选即将过期的数据淘汰 (建议使用)
volatile-random: 从已设置过期时间的数据集合中随机挑选数据淘汰
allkeys-lru: 使用 LRU 算法从所有数据集合中淘汰数据
allkeys-random: 从数据集合中任意选择数据淘汰
no-enviction: 禁止淘汰数据
来源: http://www.bubuko.com/infodetail-3345158.html