什么是Redis
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API,是现在最受欢迎的NoSQL(Not Only SQL)非关系型数据库之一;其的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用;和Memcached类似,它支持存储的value类型相对更多,包括strings(字符串)、lists(链表)、sets(集合)、zset(sorted sets --有序集合)和hashes(哈希类型),这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的;在此基础上,redis支持各种不同方式的排序,与memcached一样,为了保证效率,数据都是缓存在内存中
什么是关系/非关系型数据库
关系型数据库
***关系型数据库是依据关系模型来创建的数据库
***所谓关系模型就是“一对一、一对多、多对多”等关系模型,关系模型就是指二维表格模型,因而一个关系型数据库就是由二维表及其之间的联系组成的一个数据组织
***关系型数据可以很好地存储一些关系模型的数据,比如一个老师对应多个学生的数据(“多对多”),一本书对应多个作者(“一对多”),一本书对应一个出版日期(“一对一”)
***关系模型是我们生活中能经常遇见的模型,存储这类数据一般用关系型数据库
***关系模型包括数据结构(数据存储的问题,二维表)、操作指令集合(SQL语句)、完整性约束(表内数据约束、表与表之间的约束)
常见的关系型数据库:Oracle、DB2、PostgreSQL、Microsoft SQL Server、Microsoft Access、MySQL
主要特点:
***安全(因为存储在磁盘中,不会说突然断电数据就没有了)
***容易理解(建立在关系模型上)
***相对不节省空间(因为建立在关系模型上,要遵循某些规则,好比数据中某字段值即使为空仍要分配空间)
非关系型数据库
非关系型数据库主要是基于“非关系模型”的数据库
非关系型模型有:
***列模型:存储的数据是一列列的;关系型数据库以一行作为一个记录,列模型数据库以一列为一个记录
***键值对模型:存储的数据是一个个“键值对”,比如name:haha,那么name这个键里面存的值就是haha
***文档类模型:以一个个文档来存储数据,有点类似“键值对”
常见的非关系型数据库:
列模型:Hbase 键值对模型:redis,MemcacheDB 文档类模型:mongoDB
主要特点:
***效率高(存储在内存中)
***相对不安全(断电丢失数据,但其中redis可以同步数据到磁盘中),现在很多非关系型数据库都开始支持转存到磁盘中
Redis的安装使用
软件下载官网:RedisRedishttps://redis.io/中文网:Redis中文网 - Redis开发与运维技术、Redis教程、使用手册
https://redis.com.cn/redis安装:
tar zxf redis-6.2.4.tar.gz
yum install -y gcc
make && make install
##如有以上反馈可以尝试删除解压目录后重新解压后再进行编译安装;或者安装对应的软件
配置启动脚本:
##vim redis-6.2.4/utils/install_server.sh
##创建启动脚本为/etc/init.d/redis_6379(默认使用端口号,可自定义)
##vim /etc/redis/6379.conf使此实例监听所有端口
配置systemd的启动方式:
yum install -y systemd-devel
make USE_SYSTEMD=yes && make install
vim /usr/lib/systemd/system/redis.service
vim /etc/redis/redis.conf
其实也可以使用redis-server启动:
Redis中的常用指令
config get * ##查看配置
select 1 ##选择数据库
flushdb ##清空当前数据库
flushall ##清空所有数据库
move key 1 ##移动key
del key ##删除
rename oldkey newkey ##改名
expire key 10 ##设置过期时间
persist key ##设置持久化
keys user* ##查询
exists key ##判断是否存在
Redis的主从复制配置
1、介绍:
像MySQL一样,redis是支持主从复制的,而且也支持一主多从以及多级从结构;主从结构,一是为了纯粹的冗余备份,二是为了提升读性能,比如很消耗性能的SORT就可以由从服务器来承担;redis的主从同步是异步进行的,这意味着主从同步不会影响主的逻辑,当一个或多个slave与master进行初次同步数据时,master可以继续处理client发来的请求,即不会降低redis的处理性能;主从架构中,可以考虑关闭主服务器的数据持久化功能,只让从服务器进行持久化,这样可以提高主服务器的处理性能
在主从架构中,从服务器通常被设置为只读模式,这样可以避免从服务器的数据被误修改。但是从服务器仍然可以接受CONFIG等指令,所以还是不应该将从服务器直接暴露到不安全的网络环境中;如果必须如此,那可以考虑给重要指令进行重命名,来避免命令被外人误执行。
2、原理:
从服务器会向主服务器发出SYNC指令,当主服务器接到此命令后,就会调用BGSAVE指令来创建一个子进程专门进行数据持久化工作,也就是将主服务器的数据写入RDB文件中,在数据持久化期间,主服务器将此期间执行的写指令都缓存在内存中;在BGSAVE指令执行完成后,主服务器会将持久化好的RDB文件发送给从服务器,从服务器接到此文件后会将其存储到磁盘上,然后再将其读取到内存中,这个动作完成后,主服务器会将这段时间缓存的写指令再以redis协议的格式发送给从服务器;另外,即使有多个从服务器同时发来SYNC指令,主服务器也只会执行一次BGSAVE,然后把持久化好的RDB文件发给多个下游
##某主机一旦成为slave,则其上的数据会被清空
在redis2.8版本之前,如果从服务器与主服务器因某些原因断开连接的话,都会进行一次主从之间的全量的数据同步,而在2.8版本之后,redis支持了效率更高的增量同步策略,这大大降低了连接断开的恢复成本;主服务器会在内存中维护一个缓冲区,缓冲区中存储着将要发给从服务器的内容,从服务器在与主服务器出现网络瞬断之后,从服务器会尝试再次与主服务器连接,一旦连接成功,从服务器就会把“希望同步的主服务器ID”和“希望请求的数据的偏移位置(replication offset)”发送出去,主服务器接收到这样的同步请求后,首先会验证主服务器ID是否和自己的ID匹配,其次会检查“请求的偏移位置”是否存在于自己的缓冲区中,如果两者都满足的话,主服务器就会向从服务器发送增量内容;增量同步功能需要服务器端支持全新的PSYNC指令,这个指令只有在redis-2.8之后才具有
3、配置:
环境:master_IP=172.25.100.11=boke1 slave_IP=172.25.100.12=boke2
##在master端关闭保护模式并打开监听端口,重启redis
##在slave端添加以上配置,重启redis
4、测试
Redis的Sentinel分布式系统
在Redis主从架构中,当主服务器宕机后,从服务器不能够自动切换成主服务器,为了解决这个问题,可以配置Redis的Sentinel分布式系统来解决此问题;此系统的主要功能有:
监控(Monitoring):Sentinel会不断地检查主从架构中主服务器和从服务器是否运作正常
提醒(Notification):当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知
自动故障迁移(Automatic failover):当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器从属此新主
环境:
master:boke1 IP=172.25.100.11
slave1:boke2 IP=172.25.100.12
slave2:boke3 IP=172.25.100.13
配置:
##配置sentinel文件并同步给集群中的所有redis节点
##sentinel配置文件中修改内容; 2表示sentinel认为mater宕机的认同票数,此集群中有三个节点故为两票
测试:
##指定sentinel配置文件的方式打开集群中所有节点的sentinel
##停掉master节点的redis
##此时boke2节点成为新晋master,原从属boke1的节点boke3现从属boke2
##再次启动boke1节点的redis后其自动从属新晋节点boke2
Redis持久化
Redis提供两种持久化机制:RDB(Redis DataBase)和 AOF(Append-only file),对于应该选择RDB还是AOF,官方的建议是两个同时使用,这样可以提供更可靠的持久化方案
RDB
RDB方式是将redis某一时刻的数据持久化到磁盘中,是一种快照式的持久化方法;redis在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件;正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的;对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了redis极高的性能;如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效;但如果对数据的完整性非常敏感,那么RDB方式就不太适合,因为即使每5分钟持久化一次,当redis故障时,仍然会有近5分钟的数据丢失
AOF
AOF方式是将执行过的写指令记录下来,在数据恢复时按照从前到后的顺序再将指令都执行一遍;在重写即将开始之际,redis会创建(fork)一个“重写子进程”,这个子进程会首先读取现有的AOF文件,并将其包含的指令进行分析压缩并写入到一个临时文件中,与此同时,主工作进程会将新接收到的写指令一边累积到内存缓冲区中,一边继续写入到原有的AOF文件中,这样做是保证原有的AOF文件的可用性,避免在重写过程中出现意外;当“重写子进程”完成重写工作后,它会给父进程发一个信号,父进程收到信号后就会将内存中缓存的写指令追加到新AOF文件中,当追加结束后,redis就会用新AOF文件来代替旧AOF文件,之后再有新的写指令,就都会追加到新的AOF文件中了,在同样数据规模的情况下,AOF文件要比RDB文件的体积大,而且AOF方式的恢复速度也要慢于RDB方式
##在redis配置文件中启用AOF的持久化方式
save 900 1 #当有一条Keys数据被改变时,900秒刷新到Disk一次
save 300 100 #当有100条Keys数据被改变时,300秒刷新到Disk一次
save 60 10000 #当有10000条Keys数据被改变时,60秒刷新到Disk一次
appendonly yes #启用AOF持久化方式
appendfsync everysec #每秒钟强制写入磁盘一次
##测试AOF持久化效果
Redis Cluster集群
Redis集群不是使用一致性哈希,而是使用哈希槽;整个redis集群有16384个哈希槽,决定一个key应该分配到那个槽的算法是:计算该key的CRC16结果再模16834
更多信息请参考以下官方文档
Redis 集群教程https://redis.com.cn/topics/cluster-tutorial.html配置:
##创建6个redis实例并运行;也可运用原码包中的脚本创建
redis-cli --cluster create 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006 --cluster-replicas 1
##创建集群;--cluster-replicas 1表示为每一个主服务器配一个从服务器
##查看集群,测试集群功能;此时通过7004端口登陆时,可以写入,但是是将写的请求重定向到其master端7001从而实现的
##停掉7001主服务器,其下的从服务器7004自动顶上来成为新的master,此时集群仍可使用
##停掉新晋master后,因为此段有5461个哈希槽数据无法操作
##恢复redis集群并创建新的redis实例且启用
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7002
##创建集群中的新增节点
##为新增master节点分配哈希槽,此处为平均分配
redis-cli --cluster add-node 127.0.0.1:7008 127.0.0.1:7002 --cluster-slave --cluster-master-id 1de4973c46b9b908b994d66fdbdfbb84c5a55fdd
##为新增的master节点添加slave
tips:可以通过chkconfig来限制脚本启动方式的服务的开机自启
Redis结合数据库
环境:
boke1 apache服务器、gearman服务器 IP=172.25.100.11
boke2 redis服务器 IP=172.25.100.12
boke3 数据库服务器 IP=172.25.100.13
boke1配置:
yum install -y httpd php php-mysql
yum install -y php-pecl-redis-2.2.8-1.el7.x86_64.rpm
yum install -y php-pecl-igbinary-1.2.1-1.el7.x86_64.rpm
##apache发布文件/var/www/html/test.php
boke2配置:
##配置redis服务并保证角色为master,以满足写的权限
boke3配置:
yum install -y mariadb-server
##安装数据库服务软件并配置实验素材数据
以上配置完成后,启动boke1的apache服务后在浏览器访问测试文件test.php
##首次访问是从数据库取的数据,显示数据来源为mysql
##刷新页面后显示数据来源为redis
##此时在数据库更新数据后redis端不会同步数据
##此时在redis端删除1的值后刷新页面可重新获取到数据库中更新到的数据,但此时是全部重新获取状态
上述,我们已经实现了redis作为mysql的缓存服务器,但是如果更新了mysql中的数据,redis中仍然会有对应的KEY,数据就不会更新,这种情况下就会出现mysql和redis数据不一致的现象,虽可以通过删除redis键值重现刷新页面获取新数据,但此种方式可行性不高;所以接下来针对此种情况做下优化
优化目的:为了达到数据库数据发生更改后的同时redis中数据会自动更新的效果
mysql服务器端boke3配置:
unzip lib_mysqludf_json-master.zip
##安装lib_mysqludf_json;lib_mysqludf_json UDF库函数将关系数据映射为JSON格式,通常数据库中的数据映射为JSON格式,是通过程序来转换的
gcc $(mysql_config --cflags) -shared -fPIC -o lib_mysqludf_json.so lib_mysqludf_json.c
##在解压目录下更新插件,使用mysql_config需要安装mariadb-devel开发包
##查看mysql的插件目录
cp lib_mysqludf_json.so /usr/lib64/mysql/plugin/
##拷贝lib_mysqludf_json.so模块,文件在解压目录下
##注册UDF函数并查看
tar zxf gearman-mysql-udf-0.6.tar.gz
yum install -y libgearman-devel-1.1.12-18.el7.x86_64.rpm
yum install -y libgearman-1.1.12-18.el7.x86_64.rpm
yum install -y libevent-devel-2.0.21-4.el7.x86_64.rpm
cd gearman-mysql-udf-0.6/ --->>./configure --libdir=/usr/lib64/mysql/plugin --->>make & make install
##编译安装gearman-mysql-udf,以上安装包为其开发包及所需依赖包;这个插件是用来管理调用 Gearman的分布式的队列
##注册UDF函数并查看
##指定gearman的服务信息
##编写mysql触发器
mysql < test.sql ##将触发器导入数据库
##查看触发器
gearman服务端boke1配置:
yum install gearmand-1.1.12-18.el7.x86_64.rpm
yum install libgearman-1.1.12-18.el7.x86_64.rpm
yum install libgearman-devel-1.1.12-18.el7.x86_64.rpm
yum install libevent-devel-2.0.21-4.el7.x86_64.rpm
##安装gearman软件包及其依赖包
##启用gearman服务,查看其监听端口
yum install -y php-pecl-gearman-1.1.2-1.el7.x86_64.rpm
##安装php的gearman扩展模块
##编写gearman的worker端文件worker.php
nohup php worker.php &
##后台运行worker
优化完成,测试效果
##在数据库中更新数据
##redis中成功实时同步mysql中变化的数据
##在浏览器中刷新页面,数据也成功同步