数据库应用——Redis详解

                                                                                     Redis详解

一、非关系型数据库简介
1、NoSQL(NoSQL=NotOnlySQL),意思是“不仅仅是 SQL”,是非关系型数据库的总称

2、为什么需要NoSQL
(1)High performance:高并发读写
(2)Huge Storage:海量数据的高效率存储和访问
(3)High Scalability && High Availability:高可扩展性和高可用性

3、NoSQL数据库的四大分类
(1)键值存储(key-value)
(2)列存储
(3)文档数据库
(4)图形数据库


二、Redis概述
1、用C语言编写的,高性能key-walue键值对数据库

2、支持键值数据类型
(1)字符串类型:string
(2)散列类型:hash
(3)列表类型:list
(4)集合类型:set
(5)有序集合类型:zset

3、应用场景
(1)缓存
(2)任务队列(秒杀抢购等)
(3)网站访问统计
(4)数据过期处理(可精确到毫秒)
(5)应用排行榜
(6)分布式集群架构中的session分离
 

三、Redis安装
1、编译:make

2、安装:make PREFIX=/usr/local/redis install

3、交互式安装脚本:/安装包/utils/install_server.sh
    需输入redis_server目录:/usr/local/redis/bin/redis_server

4、bin文件
(1)Redis-benchmark:性能测试工具,可以在自己本地运行,看看自己本地性能如何(服务启动起来后执行)
(2)Redis-check-aof:修复有问题的AOF文件,持久化
(3)redis-check-rdb:修复有问题的dump.rdb文件
(4)Redis-sentinel:Redis集群使用,哨兵
(5)redis-server:Redis服务器启动命令
(6)redis-cli:客户端,操作入口

四、Redis基本操作
1、连接
    redis-cli -h 127.0.0.1 -p 6379 -a password

2、查看命令的帮助
    help

3、数据库常用命令操作
(1)set:存放数据
(2)keys:获取符合规则的键值列表
(3)exists:判断键值是否存在
        exists key:确认一个key是否存在
(4)type:获取 key 对应的 value 值类型
(5)rename:对已有 key 进行重命名(强制覆盖)
(6)renamenx:对已有 key 进行重命名,并检测新名是否存在。
(7)dbsize:查看当前数据库中 key 的数目
(8)set key value:设置key和value
(9)get key:获取key的value
(10)del key:删除一个key
(11)type key:返回值的类
(12)keys pattern:返回满足给定pattern的所有key
(13)random key:随机返回key空间的一个key
(14)rename oldname newname:重命名
(15)select index:选择第0~15中的库
(16)move key dbindex:移动当前数据库中的key到dbindex数据库
(17)FLUSHDB:清除当前库数据(危险命令
(18)FLUSHALL:清除所有库数据(危险命令
 

五、Redis事务
1、事务简介
    事务提供了一种将多个命令请求打包,然后一次性、按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断事务而去执行其他客户端命令。可以一次执行多个命令,本质是一组命令的集合。

2、Redis事务特点
(1)事务中的命令序列执行的时候是原子性的,也就是说,其不会被其他客户端的命令中断. 这和传统的数据库的事务的属性是类似的.
(2)Redis事务中的命令序列是原子执行的, 但是事务中的命令序列执行可以部分成功
(3)不支持传统数据库中的回滚操作
(4)redis事务只保证讲命令序列中操作的结果提交到内存中,不一定永久保存,但传统关系型数据库事务完成,数据永久存储

3、事务创建
(1)multi:事务开始
(2)exec:提交事务
(3)discard:结束事务
(4)watch:执行乐观锁(2.2版本以上)  
(5)unwatch:取消乐观锁

4、事务实例


5、错误处理
(1)入队错误
如果一个事务在入队命令的过程中,出现了命令不存在,或者命令的格式不正确等情况入列时错误,会终止整个事务
(2)执行错误
执行错误通常都是一些不能在入队时被服务器发现的错误, 这些错误只会在命令实际执行时被触发。即使在事务的执行过程中发生了错误, 服务器也不会中断事务的执行, 它会继续执行事务中余下的其他命令, 并且已执行的命令(包括执行命令所产生的结果)不会被出错的命令影响
 

六、Redis数据持久化
1、持久化使用方式
(1)RDB持久化
指定时间间隔内将内存中的数据集快照写入指定磁盘
(2)AOF持久化
将以日志形式记录服务器的每个操作,在启动时会读取该文件来写入数据库
(3)无持久化
仅做缓存服务器使用
(4)同时使用RDB和AOF

2、RDB持久化
(1)优势
只包含一个文件,对于压缩备份来说很容易
性能最大化
③如果数据集很大,启动效率会更高
(2)劣势
①定时写入机制有更大的数据丢失风险
②由于 RDB 是通过 fork 子进程来协助完成数据持久化工作的,因此当数据集较大时,可 能会导致整个服务器停止服务几百毫秒,甚至是 1 秒钟
(3)配置
①save 900 1:每900秒至少一个变化
②save 300 10:每300秒至少10个变化
③sanve 60 10000:每60秒至少10000个变化
④dbfilename dump.rdb:保存的文件名
⑤dir ./:保存路径
⑥rdbcompression yes:是否压缩
⑦rdbchecksum yes:导入时是否检查
⑧stop-writes-on-bgsave-error yes:入股持久化出错,主进程是否停止写入
(4)手动持久化
①save:会阻塞当前Redis服务器,直到持久化完成,线上应该禁止使用
②bgsave:该触发方式会fork一个子进程,由子进程负责持久化过程,因此阻塞只会发生在fork子进程的时候

3、AOF持久化
(1)优势
①更高的数据安全性
总共3种同步策略:每秒同步、每次修改同步和不同步
采用追加方式写入日志文件,写入过程宕机不会导致之前数据出问题,redis-check-aof工具来解决数据一致性的问题
③如果日志过大,Redis 可以自动启用 rewrite 机制
④包含格式清晰已于理解的日志文件用于记录所有操作,也可根据该文件完成数据重建
(2)劣势
①对于相同数量的数据集而言,AOF 文件通常要大于 RDB 文件
②AOF机制 每次发生的数据变化都会被立即记录到磁盘中,这种方式在效率上是最低的
恢复大数据集时,速度较低
(3)配置
①appendonly yes:是否开启AOF
②appendfilename "appendonly.aof":默认文件名
③appendfsync everysec:每秒同步
④appendfsync always:每条命令同步
⑤appendfsync no:不处理
 

七、Redis备份与恢复
1、数据备份
(1)AOF持久化
(2)RDP持久化
(3)SAVE命令
2、数据恢复
(1)获取备份目录:config get dir
(2)停止redis服务
(3)拷贝备份文件到指定目录
(4)重启服务

八、Redis性能管理
1、如何查看redis性能
    nfo命令输出的数据可以分为10个分类,分别是:
    server,clients,memory,persistence,stats,replication,cpu,commandstats,cluster,keyspace

2、内存memory
used_memory:由 Redis 分配器分配的内存总量,以字节(byte)为单位
used_memory_human:以人类可读的格式返回 Redis 分配的内存总量
used_memory_rss:从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps等命令的输出一致
used_memory_rss_human:以人类可读的格式,从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps等命令的输出一致。
used_memory_peak:redis的内存消耗峰值(以字节为单位)
used_memory_peak_human:以人类可读的格式返回redis的内存消耗峰值
used_memory_peak_perc:(used_memory/ used_memory_peak) *100%
used_memory_overhead:Redis为了维护数据集的内部机制所需的内存开销,包括所有客户端输出缓冲区、查询缓冲区、AOF重写缓冲区和主从复制的backlog。
used_memory_startup:Redis服务器启动时消耗的内存
used_memory_dataset:used_memory—used_memory_overhead
used_memory_dataset_perc:100%*(used_memory_dataset/(used_memory—used_memory_startup))
total_system_memory:整个系统内存
total_system_memory_human:以人类可读的格式,显示整个系统内存
used_memory_lua:Lua脚本存储占用的内存
used_memory_lua_human:以人类可读的格式,显示Lua脚本存储占用的内存
maxmemory:Redis实例的最大内存配置
maxmemory_human:以人类可读的格式,显示Redis实例的最大内存配置
maxmemory_policy:当达到maxmemory时的淘汰策略
mem_fragmentation_ratio:used_memory_rss/ used_memory,内存碎片率
mem_allocator:内存分配器

active_defrag_running:表示没有活动的defrag任务正在运行,1表示有活动的defrag任务正在运行(defrag:表示内存碎片整理

3、因内存交换引起的性能问题
    内存使用率是Redis服务最关键的一部分。如果Redis实例的内存使用率超过可用最大内存 (used_memory > 可用最大内存),那么操作系统开始进行内存与swap空间交换,把内存中旧的或不再使用的内容写入硬盘上(硬盘上的这块空间叫Swap分区),以便留出新的物理内存给新页或活动页(page)使用。
    如果Redis进程上发生内存交换,那么Redis和依赖Redis上数据的应用会受到严重的性能影响。 通过查看used_memory指标可知道Redis正在使用的内存情况,如果used_memory>可用最大内存,那就说明Redis实例正在进行内存交换或者已经内存交换完毕。

4、跟踪内存使用率
    若是在使用Redis期间没有开启rdb快照或aof持久化策略,那么缓存数据在Redis崩溃时就有丢失的危险。因为当Redis内存使用率超过可用内存的95%时,部分数据开始在内存与swap空间来回交换,这时就可能有丢失数据的危险。
    通过减少Redis的内存占用率,来避免这样的问题,或者使用下面的技巧来避免内存交换发生
(1)假如缓存数据小于4GB,就使用32位的Redis实例。因为32位实例上的指针大小只有64位的一半,它的内存空间占用空间会更少些。 这有一个坏处就是,假设物理内存超过4GB,那么32位实例能使用的内存仍然会被限制在4GB以下。 要是实例同时也共享给其他一些应用使用的话,那可能需要更高效的64位Redis实例,这种情况下切换到32位是不可取的。 不管使用哪种方式,Redis的dump文件在32位和64位之间是互相兼容的, 因此倘若有减少占用内存空间的需求,可以尝试先使用32位,后面再切换到64位上。
(2)尽可能的使用Hash数据结构。因为Redis在储存小于100个字段的Hash结构上,其存储效率是非常高的。所以在不需要集合(set)操作或list的push/pop操作的时候,尽可能的使用Hash结构。比如,在一个web应用程序中,需要存储一个对象表示用户信息,使用单个key表示一个用户,其每个属性存储在Hash的字段里,这样要比给每个属性单独设置一个key-value要高效的多。 通常情况下倘若有数据使用string结构,用多个key存储时,那么应该转换成单key多字段的Hash结构。 如上述例子中介绍的Hash结构应包含,单个对象的属性或者单个用户各种各样的资料。Hash结构的操作命令是HSET(key, fields, value)和HGET(key, field),使用它可以存储或从Hash中取出指定的字段。
(3)设置key的过期时间。一个减少内存使用率的简单方法就是,每当存储对象时确保设置key的过期时间。倘若key在明确的时间周期内使用或者旧key不大可能被使用时,就可以用Redis过期时间命令(expire,expireat, pexpire, pexpireat)去设置过期时间,这样Redis会在key过期时自动删除key。 假如你知道每秒钟有多少个新key-value被创建,那可以调整key的存活时间,并指定阀值去限制Redis使用的最大内存。
(4)回收key。在Redis配置文件中(一般叫Redis.conf),通过设置“maxmemory”属性的值可以限制Redis最大使用的内存,修改后重启实例生效。 也可以使用客户端命令config set maxmemory 去修改值,这个命令是立即生效的,但会在重启后会失效,需要使用config rewrite命令去刷新配置文件。 若是启用了Redis快照功能,应该设置“maxmemory”值为系统可使用内存的45%,因为快照时需要一倍的内存来复制整个数据集,也就是说如果当前已使用45%,在快照期间会变成95%(45%+45%+5%),其中5%是预留给其他的开销。 如果没开启快照功能,maxmemory最高能设置为系统可用内存的95%
volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据
volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰
volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰
allkeys-lru:使用LRU算法从所有数据集合中淘汰数据
allkeys-random:从数据集合中任意选择数据淘汰
⑥no-enviction:禁止淘汰数据。
 

九、redis安全管理
Redis被设计成仅有可信环境下的可信用户才可以访问。这意味着将Redis实例直接暴露在网络上或者让不可信用户可以直接访问Redis的tcp端口或Unix套接字,是不安全的。
1、网络安全
    bind 127.0.0.1:将Redis绑定在单个接口上
    port 8888:修改Redis默认端口

2、认证特性
    虽然Redis没有尝试去实现访问控制,但是提供了一个轻量级的认证方式,可以编辑redis.conf文件来启用。
    当认证授权方式启用后,Redis将会拒绝来自没有认证的用户的任何查询。一个客户端可以通过发送AUTH命令并带上密码来给自己授权。
(1)初始化redis密码
在配置文件中有个参数: requirepass  这个就是配置redis访问密码的参数。(生成加密密码:echo "qwertyuiopasdfghjklzxcvbnm" | sha256sum)
(2)使用密码登陆redis
登陆时使用 -a选项加密码
登陆到redis上使用auth 进行密码验证:
①config get requirepass:查询密码
②config set requirepass 密码字符串:设置密码

3、限制Redis文件目录访问权限
    设置redis的主目录权限为700;如果redis配置文件独立于redis主目录,权限修改为600。
    对配置文件设置特殊权限 文件权限除了r、w、x外还有s、t、i、a权限

4、禁止使用root启动redis
    为Redis服务创建单独的用户和相应目录

5、禁用或重命名危险命令
    rename-command FLUSHDB zhangsan:重命名FLUSHDB命令
    rename-command FLUSHALL “”:禁用FLUSHALL命令

6、配置防火墙限制客户端登录

7、redis-cli监控命令
(1)info命令是redis基本监控
(2)查看和杀掉客户端连接
    CLIENT LIST
    CLIENT KILL 127.0.0.1:58322
(3)stat命令:显示key数量、内存、客户端数量、QPS情况
    redis-cli --stat
(4)查看redis延迟
    redis-cli --latency
(5)monitor命令会监控当前redis接受的命令和数据内容,这个命令会比较消耗资源,根据官网的测试,QPS会下降到原先的50%,需要谨慎使用
    redis-cli monitor
(6)使用bigkeys查找占用空间较大的key
    redis-cli --bigkeys


十、Redis主从复制
1、复制原理
(1)Slave启动成功连接到master后会发送一个sync命令;
(2)Master接到命令启动后的存盘进程,同时收集所有接收到的用于修改数据集命令,在后台进程执行完毕之后,master将传送整个数据文件到slave,以完成一次完全同步;
(3)全量复制:而slave服务在数据库文件数据后,将其存盘并加载到内存中;
(4)增量复制:Master继续将新的所有收集到的修改命令依次传给slave,完成同步;
(5)但是只要是重新连接master,一次完全同步(全量复制)将被自动执行|

2、配置
(1)配从不配主
(2)从库配置:slaveof [主库IP] [主库端口];
(3)多实例配置文件细节操作
①修改端口:port 6379
②开启daemonize yes
③pidfile:指定pid文件
④logfile:指定log文件
⑤dbfilename:指定dump.rdb文件
(4)常用主从复制模式
一主二仆
    一个Master,两个Slave,Slave只能读不能写;当Slave与Master断开后需要重新slave of连接才可建立之前的主从关系;Master挂掉后,Master关系依然存在,Master重启即可恢复
薪火相传
    上一个Slave可以是下一个Slave的Master,Slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个slave的Master,如此可以有效减轻Master的写压力。如果slave中途变更转向,会清除之前的数据,重新建立最新的
反客为主
    当Master挂掉后,Slave可键入命令 slaveof no one使当前redis停止与其他Master redis数据同步,转成Master redis
(5)反客为主的自动版,能够后台监控Master库是否故障,如果故障了根据投票数自动将slave库转换为主库。该模式需要使用到redis哨兵


十一、Redis哨兵
1、为什么要使用哨兵
    哨兵(Sentinel)主要是为了解决在主从复制架构中出现宕机的情况,主要分为两种情况:
(1)从Redis宕机
    这个相对而言比较简单,在Redis中从库重新启动后会自动加入到主从架构中,自动完成同步数据。在Redis2.8版本后,主从断线后恢复的情况下实现增量复制。
(2)主Redis宕机
    这个相对而言就会复杂一些,需要以下2步才能完成:
    ①在从数据库中执行SLAVEOF NO ONE命令,断开主从关系并且提升为主库继续服务
    ②将主库重新启动后,执行SLAVEOF命令,将其设置为其他库的从库,这时数据就能更新回来

2、Redis实现的sentinel哨兵机制
(1)监控(Monitoring):
    Sentinel会不断地检查你的主服务器和从服务器是否运作正常
(2)提醒(Notification):
    当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知
(3)自动故障迁移(Automatic failover):
    当一个主服务器不能正常工作时,Sentinel 会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器

3、哨兵配置
(1)在Master对应redis.conf同目录下新建sentinel.conf文件,名字绝对不能错

(2)在sentinel.conf文件中填入内容:
①sentinel monitor 被监控数据库名字(自己起名字) ip port 1
    说明:上面最后一个数字1,表示主机挂掉后slave投票看让谁接替成为主机,得票数多少后成为主机
②sentinel down-after-milliseconds mymaster 30000
    指定了 Sentinel 认为master已经断线所需的毫秒数
③sentinel parallel-syncs mymaster 1
    指定了在执行故障转移时, 最多可以有多少个slave同时对新的master进行同步, 这个数字越小, 完成故障转移所需的时间就越长
④sentinel failover-timeout mymaster 180000
    failover-timeout 指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟

(3)启动sentinel
    redis-sentinel /etc/redis/sentinel.conf

(4)查看状态
    info sentinel


十二、Redis集群-cluster
1、clushter简介
    cluster是sentinel和主从模式的结合体,通过cluster可以实现主从和master重选功能,所以如果配置两个副本三个分片的话,就需要六个Redis实例。因为Redis的数据是根据一定规则分配到cluster的不同机器的,当数据量过大时,可以新增机器进行扩容。
    Redis 集群实现了对Redis的水平扩容,即启动N个redis节点,将整个数据库分布存储在这N个节点中,每个节点存储总数据的1/N

2、cluster特点
(1)多个redis节点网络互联,数据共享
(2)所有的节点都是一主一从(也可以是一主多从),其中从不提供服务,仅作为备用
(3)不支持同时处理多个key(如MSET/MGET),因为redis需要把key均匀分布在各个节点上,并发量很高的情况下同时创建key-value会降低性能并导致不可预测的行为
(4)支持在线增加、删除节点
(5)客户端可以连接任何一个主节点进行读写

3、集群配置
(1)制作6个实例,6379,6380,6381,6382,6383,6384.conf,并启动
    cluster-enabled  yes:开启集群
    cluster-config-file nodes-6379.conf:集群的配置  配置文件首次启动自动生成6380、6881、6382
    cluster-node-timeout  15000:设定节点失联时间,超过该时间(毫秒),集群自动进行主从切换
    appendonly  yes:aof日志开启  有需要就开启,它会每次写操作都记录一条日志
(2)创建集群
①搭建ruby环境
    1)Redis 官方提供了 redis-trib.rb 这个工具,就在解压目录的 src 目录中,第三步中已将它复制到 /usr/local/bin 目录中
    2)如果redis版本比较低,则需要安装ruby:yum -y install ruby ruby-devel rubygems rpm-build
    3)安装redis集群接口:gem install redis
        a.yum install centos-release-scl-rh:会在/etc/yum.repos.d/目录下多出一个CentOS-SCLo-scl-rh.repo源
        b.yum install rh-ruby23  -y
        c.scl enable rh-ruby23 bash:必要一步
        d.ruby -v:查看安装版本
        e.gem install redis
②创建集群:
1)将六个节点合成一个集群(组合之前,请确保所有redis实例启动后,nodes-xxxx.conf文件都生成正常)
    redis-trib.rb create --replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384

2)哈希槽
    Redis 集群的数据分片 Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念
    一个 Redis 集群包含 16384 个插槽(hash slot), 数据库中的每个键都属于这 16384 个插槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中 CRC16(key) 语句用于计算键 key 的 CRC16 校验和
    集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个主节点,那么:
        a.节点 A 包含 0 到 5500号哈希槽.
        b.节点 B 包含5501 到 11000 号哈希槽.
        c.节点 C 包含11001 到 16384号哈希槽.
③查看测试集群
    登录redis节点,通过 cluster nodes 命令查看集群信息。一个集群至少要有三个主节点。选项 --replicas 1 表示我们希望为集群中的每个主节点创建一个从节点。
集群操作
1)登录
redis-cli -c -h 192.168.30.128 -p 6382 -a 123456:-c,使用集群方式登录
2)查看集群信息
CLUSTER INFO:集群状态

3)列出节点信息
CLUSTER NODES:列出节点信息这里与nodes.conf文件内容相同

4)写入数据
set key111 aaa

5)redis cluster集群是去中心化的,每个节点都是平等的,连接哪个节点都可以获取和设置数据。当然,平等指的是master节点,因为slave节点根本不提供服务,只是作为对应master节点的一个备份。
6)redis集群会将每个实例单独启用10000偏移的集群端口,设置防火墙时下需要同时开启此端口
新加节点
1)复制编辑新节点conf文件并启动实例
2)进入集群将新节点加入集群
    CLUSTER MEET 127.0.0.1 6386
    所有新加节点都为master节点
3)更换节点身份:登录想要作为slave节点的实例将该节点更换为指定节点的slave节点
    redis-cli -c -h 127.0.0.1 -p 6386  cluster replicate 3b9fbde7d4ef507fc5982e42d13f483ce569b2f6


十三、php使用redis
1、安装php的redis扩展模块
(1)https://github.com/phpredis/phpredis/releases
(2)解包后进入目录
(3)/usr/local/php5/bin/phpize(可能需要安装autoconf)
(4)./configure --with-php-config=/usr/local/php5/bin/php-config
(5)make && make install
(6)php.ini中添加
extension_dir = "/usr/local/php5/lib/php/extensions/no-debug-zts-20121212/"
extension=redis.so
(7)重启apache

十四、redis与mysql结合实现数据同步
多为开发人员使用,可参考以下文档:
https://blog.csdn.net/hanchao5272/article/details/79729576
https://blog.csdn.net/qq_32217519/article/details/71191521
https://blog.51cto.com/4925054/1910483

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值