数据库相关
存储数据类型分类:
结构化数据:可以通过二维表格形式表述这个数据
非结构化数据:不方便以二维表格的形式表述这种类型的数据
数据库分类
根据不同种存储数据类型分类分成两种不同类型的数据库:
结构化数据库sql
里面存储的数据类型是结构化数据,别称关系型数据库
非结构化数据库nosql
里面存储的数据类型是非结构化数据,别称非关系型数据库
列举
关系型数据库
一种结构化的数据库,创建在关系模型基础上一般面向于记录包括oracle、mysql、sqls erver、microsoft access、db2等
非关系型数据库
除了主流的关系型数据库外的是数据库,都认为是非关系型包括:Redis、mongbd、hbase、couhdb等
非关系型数据库产生的背景
high performance 对数据库高并发读写需求
huge storage 对海量数据高效存储与访问需求
high scalability && high availability 对数据库高可扩展性与高可用性需求
redis数据库和memcached设局库对比
redis
简介
redis基于内存运行并支持持久化
采用key-value(键值对)的存储形式(关键词)
优点:
具有极高的数据读写速度
支持丰富的数据类型
支持数据的持久化(内存写到磁盘,通过日志保证其数据不会丢失)
原子化
支持数据备份
Redis支持的数据类型
string(字符串)
是redis最基本的类型,可理解成与mamcached一样的类型,一个key对应一个value
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象
最大能存储512MB
设置键值对:set 键 值
获取键的值:get 键
让键的值自增长:incr 键
让键的值自降:decr 键
值自增长的幅度:incrby 键 3
值自降的幅度:decrby 键 3
hash(哈希)
redis hash是一个键值对集合,是一个string类型的field和value的映射表,适用于存储对象
添加hash数据:Hset 键 key 值
Hset hash1 key1 a
获取hash数据:Hget hash1 key1
获取多个hash数据Hmget hash1 field1
list(列表)
是简单的字符串列表,按照插入顺序排序。可以添加一个元素到列表的头部(左边)或者尾部(右边)。
实例:
lpush:从左边推入值
Lpush list1
lpop:从左边弹出值
Lpop list1
rpush:从右边推入值
rpop:从右边弹出值
llen:查看某个list数据类型的长度
Lrange list1 列出所有list1的值
set(集合)
是string类型的无序集合,通过hash表实现,所以添加删除查找的复杂 度都是0(1)
sadd命令:添加string元素到key对应的set集合,成功返回1,若已存在则返回0
sadd key member
scard:查看set数据中存在的数据个数
sismember:判断set数据中是否存在某个元素
srem:删除某个set数据中的元素
Smembers set1 (列出set1的所有值)
zset(sortedset:有序集合)
是string类型元素的集合,且不允许重复的成员
不同的是每个元素都会关联一个bouble类型的分数。redis正式通过分数来为集合中的成员进行从小到达排序
zset成员是唯一的,但分数可以(score)重复
添加元素到集合,若已存在则跟新score
zadd key score member
zcard:查询
zrang:数据排序
五种数据类型对比
安装 redis
tar zxvf redis-5.0.4.tar.gz
cd redis-5.0.4/
make
make install PREFIX=/usr/local/redis
cd /usr/local/redis/
ln -s bin/* /usr/sbin
cd
cd redis-5.0.4/utils/
./install_server.sh
Please select the redis port for this instance: [6379] #选择端口,直接enter,保持默认
Please select the redis config file name [/etc/redis/6379.conf] #配置文件路径
Please select the redis log file name [/var/log/redis_6379.log] #日志路径
Please select the data directory for this instance [/var/lib/redis/6379] #数据保存路径
Please select the redis executable path [] /usr/local/redis/bin/redis-server #执行路径,手动输入
回车安装
netstat -anpt | grep redis #查看服务端口启动情况
/etc/init.d/redis_6379 stop #停止redis服务
/etc/init.d/redis_6379 start #启动redis服务
/etc/init.d/redis_6379 restart #重启redis服务
/etc/init.d/redis_6379 status #查看状态
连接到数据库
redis-cli
连接到某ip的地址
vi /etc/reis
bind 192.168.110.40 127.0.0.1 #默认只有127,其他需要自己添加
/etc/init.d/redis_6379 restart #重启服务
redis-cli -h 192.168.110.40
redis五种数据类型操作
string
192.168.110.40:6379> set a 1 #设置键a的值为1
192.168.110.40:6379> get a #查看a的值
192.168.110.40:6379> type a #查看键a的类型
192.168.110.40:6379> incr a #让a的值自自增长,默认为1
192.168.110.40:6379> decr a #让a的值自降,默认为1
192.168.110.40:6379> incrby a 3 #让a自增长3
192.168.110.40:6379> decrby a 3 #让a自降3
hash(哈希)
192.168.110.40:6379> hset hash1 key1 a #在hash1中写入key1值为a
192.168.110.40:6379> hset hash1 key2 b #在hash1中写入key2值为b
192.168.110.40:6379> hset hash1 key3 c #在hash1中写入key3值为c
192.168.110.40:6379> hset hash1 field1 aa field2 bb #在hash1中写入字段field1和field2,值分别为aa和bb
192.168.110.40:6379> hget hash1 key1 #查看hash1中key1的值
192.168.110.40:6379> hmget hash1 key1 key2 key3 #查看hash1中key1,2,3的值
192.168.110.40:6379> hmget hash1 field1 #查看hash1中字段field1的值(可与查看字段同时使用)
192.168.110.40:6379> hmget hash1 field1 field2 #查看hash1中字段field1、field2的值
#查看包含多个字符值的时候要用到hmget
set(集合)
192.168.110.40:6379> sadd set1 pp #在set1中添元,添加成功输出1,失败(已存在)输出0
192.168.110.40:6379> scard set1 #查看set1元素的个数
192.168.110.40:6379> sismember set1 pp #查看set1中是否存在某个元素,,存在输出1,不存在输出0
192.168.110.40:6379> srem set1 hh #删除set1中的某个元素,删除成功输出1,失败(删除不存在元素)输出0
192.168.110.40:6379> smembers set1 #查看set1中的所有元素,无序排列呈现
zset
192.168.110.40:6379> zadd zset 1 a #在zset中添加元素值位a,分数为1
192.168.110.40:6379> zrangebyscore zset 0 5 #查看zset中第0位到第5为的值,按照分数从小到大排列
192.168.110.40:6379> zrangebyscore zset 0 5 withscores #带有分数查看zset中第0位到第5为的值,元素在上,分数在下
redis命令工具
redis-server #启动reids的工具
redis-benchmark #用于检测redis在本机的运行效率
redis-check-aof #修复aof持久化文件
redis-check-rdb #修复rdb持久化文件
redis-setinel #是哨兵模式启动工具
redis-benchmark选项
-h #指定服务器主机名
-p #指定服务器端口
-s #指定服务器socket
-c #指定并发连接
-n #指定请求数
-d #以字节的形式指定set/get值得数据大小
-r #set/get/ing 使用随机key,sadd使用随机值
-P #通过管道传输请求
-q #强制退出redis。仅显示query/sec使用随机值
–csv #以csv格式输出
-l #生成循环,永久执行测试
-t #仅运行以逗号分分隔得测试命令列表
-I #idle模式。仅打开n个idle连接并等待
key相关命令
keys #获取符合规则得键值列表
exists #判断键值是否存在
del #删除当前数据库指定得key
type #获取key对应得value值类型
rename(覆盖)/renamex(不覆盖):对已有的key进行重命名
dbsize #查看当前数据库中key的数目
redis多数据库操作
redis支持多数据库,默认支持16个数据库,0-15命名
多数据库相互独立,互不干扰
多数据库常用命令:多数据库键切换,多数据库间移动数据,清除数据库内数据
多数据库间切换:select 0-15
多数据库间移动数据
redis提供了一个move命令,可进行数据库间数据移动。
move 要移动的键 移动到的数据库
move f 1 #将0数据库里的f移动到1数据库
清除数据库内数据
flushdb #清空当前数据库数据
flushall #清空所有数据库数据
redis持久化
redis是运行在内存中,内存中的数据断电丢失
为了能够重用redis数据,或者防止系统故障,需要将redis中的数据写入到磁盘空间中,即持久化
持久化分类
rdb方式:创建快照的方式获取某一时刻redis中所有数据的副本
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
优势
如果采用该方式,那么整个Redis数据库将只包含一个文件。这对于文件备份而言是非常完美的。比如,可以每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
相比于AOF机制,如果数据集很大,RDB的启动效率会更高。
劣势
该方式无法保证数据的高可用性,即无法最大限度的避免数据丢失。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。
aof方式:将执行的写命令写到文件末尾,以日志的方式来记录数据变化
AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
优势
该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3种同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,则不利于数据安全。
由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。如果本次操作只是写入了一半数据就出现了系统崩溃问题,那么,在Redis下一次启动之前,可以通过redis-check-aof工具来解决数据一致性的问题。
如果日志过大,Redis可以自动启用rewrite机制。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。
劣势
对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。
二者选择的标准
取决于系统是愿意牺牲一些性能,换取更高的缓存一致性(aof),还是愿意写操作频繁的时候,不启用备份来换取更高的性能,待手动运行save的时候,再做备份(rdb)。
配置
RDB持久化配置
Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开6379.conf文件之后,我们搜索save,可以看到下面的配置信息:
save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。
save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。
save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。
AOF持久化配置
在Redis的配置文件中存在三种同步方式,它们分别是:
appendfsync always 每次有数据修改发生时都会写入AOF文件。
appendfsync everysec 每秒钟同步一次,该策略为AOF的缺省策略。
appendfsync no 从不同步。高效但是数据不会被持久化。
RDB持久化
是Redis的默认持久化方式,默认文件名dump.rdb。
触发条件
在指定的时间间隔内,执行指定次数的写操作(配置文件控制)
执行save或者是bgsave(异步)命令
执行fluhall命令,清空数据库所有数据
执行shutdown命令,保证服务器正常关闭且不丢失任何数据
优缺点
适用于大规模的数据恢复
如果业务对数据完整性和一致性要求不高,RDB是很好的选择
数据的完整性和一致性不高
备份时占用内存
通过RDB文件恢复数据
将dump.rdb文件拷贝到redis的安装目录的bin目录下,重启redis服务即可
配置文件
vi /etc/redis/6379.conf
save 900 1 # 900秒之内至少一次写操作
save 300 10 # 300秒以内至少发生10次写操作
save 60 10000 # 60秒以内至少发生10000次写操作
#只要满足其中一都会触发快照操作,注释所有的save项表示关闭RDB
dbfilename dump.rdb RDB文件名称
rdbcompression yes 是否进行压缩
AOF持久化
基础相关
此种方式Redis默认不开启,可以用来弥补RDB的不足(数据的不一致性)
基本原理
采用日志的形式来记录每个写操作,并追加到文件中。Redis重启会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
根据AOF文件恢复数据
将appendonly.aof文件拷贝到Redis的安装目录的bin目录下,重启Redis服务即可
配置文件选项
vi /etc/redis/6379.conf
appendonly yes #开启AOF持久化
appendfilename "appendonly.aof" #AOF文件名称
appendfsync always #always:同步持久化,每次发生数据变化会立刻写入磁盘
appendfsync everysec #everysec:默认推荐,每秒异步记录一次(默认值)
appendfsync no #no:不同步,交给操作系统决定如何同步
aof-load-truncated yes #忽略最后一条可能存在问题的指令
/etc/init.d/redis_6379 stop 关闭服务
/etc/init.d/redis_6379 start 开启服务
AOF的重写机制
AOF的工作原理是将写操作追加到文件中,文件的冗余内容会越来越多
当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩
AOF重写的原理
Redis会fork出一条新进程,读取内存中的数据(并没有读取旧文件) ,并重新写到一个临时文件中,最后替换旧的aof文件
AOF的重写配置
vim /etc/redis/6379.conf
no-appendfsync-on-rewrite no #在日志进行BGREWRITEAOF时,如果设置为yes表示新写操作不进行同步fsync,只是暂存在缓冲区里,避免造成磁盘IO操作冲突,等重写完成后在写入。Redis中默认为no
auto-aof-rewrite-percentage 100 #当前AOF文件大小是上次日志重写时AOF文件大小两倍时,发生BGREWRITEAOF操作
auto-aof-rewrite-min-size 64mb #当前AOF文件执行BGREWRITEAOF命令的最小值,避免刚开始启动Reids时由于文件尺寸较小导致频繁的BGREWRITEAOF
Redis性能管理
查看Redis内存使用
/usr/local/redis/bin/redis-cli
127.0.0.1:6379> info memory
# Memory
used memory:2650536 内存使用总量
used memory_ human:2.53M
used_ memory_ rss: 12120064
used_ memory_ rss_ human:1 1.56M
....
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有限的内存资源
当达到设置的最大阀值时,需选择一种key的回收策略
默认情况下回收策略是禁止删除
redis.conf配置文件中修改 maxmemory-policy属性值
volatile-lru#使用LRU算法从已设置过期时间的数据集合中淘汰数据
volatile-ttl#从已设置过期时间的数据集合中挑选即将过期的数据淘汰
volatile-random#从已设置过期时间的数据集合中随机挑选数据淘汰
allkeys-lru#使用L RU算法从所有数据集合中淘汰数据
alkeys-random#从数据集合中任意选择数据淘汰
no-enviction:#禁止淘汰数据
配置文件
vi /etc/redis/6379.conf
添加修改
maxmemory-policy volatile-lru
/etc/init.d/redis_6379 stop 关闭服务
/etc/init.d/redis_6379 start 开启服务
netstat -anpt | grep redis 查看状态