Red Hat Enterprise Linux/CentOS 7.0 发行版已将默认的数据库从 MySQL 切换到 MariaDB

  • MariaDB 数据库管理系统是 MySQL 的一个分支,主要由开源社区在维护,采用 GPL 授权许可。
  • 开发这个分支的原因之一是:甲骨文公司收购了 MySQL 后,有将 MySQL 闭源的潜在风险,因此社区采用分支的方式来避开这个风险。
  • MariaDB 的目的是完全兼容 MySQL ,包括 API 和命令行,使之能轻松成为 MySQL 的代替品。
  • yum安装mariadb

    添加yum源安装Mariadb

  • 1 、首先在 RHEL / CentOS Fedora 操作系统中添加 MariaDB YUM 配置文件 MariaDB . repo 文件。
  • #编辑创建mariadb.repo仓库文件
  • vi / etc / yum . repos . d / MariaDB . repo
  • 2 、添加 repo 仓库配置
  • [ mariadb ]
  • name = MariaDB
  • baseurl = http : //yum.mariadb.org/10.1/centos7-amd64
  • gpgkey = https : //yum.mariadb.org/RPM-GPG-KEY-MariaDB
  • gpgcheck = 1
  • yum一键安装mariadb

  • MariaDB 仓库地址添加好后,你可以通过下面的一行命令轻松安装 MariaDB
  • yum install MariaDB - server MariaDB - client - y
  • mariadb 数据库的相关命令是:
  • systemctl start mariadb #启动MariaDB
  • systemctl stop mariadb #停止MariaDB
  • systemctl restart mariadb #重启MariaDB
  • systemctl enable mariadb #设置开机启动
  • 初始化mysql

  • 在确认 MariaDB 数据库软件程序安装完毕并成功启动后请不要立即使用。为了确保数据 库的安全性和正常运转,需要先对数据库程序进行初始化操作。这个初始化操作涉及下面 5 步骤。
  • 设置 root 管理员在数据库中的密码值(注意,该密码并非 root 管理员在系统中的密 码,这里的密码值默认应该为空,可直接按回车键)。
  • 设置 root 管理员在数据库中的专有密码。
  • 随后删除匿名账户,并使用 root 管理员从远程登录数据库,以确保数据库上运行的业
  • 务的安全性。
  • 删除默认的测试数据库,取消测试数据库的一系列访问权限。
  • 刷新授权列表,让初始化的设定立即生效。
  • 确保mariadb服务器启动后,执行命令初始化

  • mysql_secure_installation
  • 创建mysql普通用户

    生产环境里不会死磕root用户,为了数据库的安全以及和其他用户协同管理数据库,就需要创建其他数据库账户,然后分配权限,满足工作需求。

  • MariaDB [( none )]> create user username@ '%' identified by 'password' ;
  • MariaDB [( none )]> use mysql ;
  • MariaDB [ mysql ]> select host , user , password from user where user = 'username' ;
  • 切换普通用户yuchao,查看数据库信息,发现无法看到完整的数据库列表

  • [ root@master ~]# mysql - uusername - p - h 127.0 . 0.1
  • MariaDB [( none )]> show databases ;
  • mysql授权sql

    mysql使用grant命令对账户进行授权,grant命令常见格式如下

  • grant 权限 on 数据库.表名 to 账户@主机名 对特定数据库中的特定表授权
  • grant 权限 on 数据库.* to 账户@主机名 对特定数据库中的所有表给与授权
  • grant 权限 1 ,权限 2 ,权限 3 on *.* to 账户@主机名 对所有库中的所有表给与多个授权
  • grant all privileges on *.* to 账户@主机名 对所有库和所有表授权所有权限
  • 退出数据库,使用root登录,开始权限设置

  • [ root@master ~]# mysql - uroot - p
  • MariaDB [( none )]> use mysql ;
  • ##授予远程登录的权限
  • MariaDB [( none )]> grant all privileges on *.* to username@ "%" identified by 'password' ;
  • MariaDB [ mysql ]> show grants for username@ "%" ;
  • MariaDB [( none )]> revoke all privileges on *.* from username@ "%" ;
  • mysql备份与恢复

    mysqldump命令用于备份数据库数据

  • [ root@master ~]# mysqldump - u root - p -- all - databases > /tmp/ db . dump
  • 进入mariadb数据库,删除一个db

  • [ root@master ~]# mysql - uroot - p
  • MariaDB [( none )]> drop database s11 ;
  • 进行数据恢复,吧刚才重定向备份的数据库文件导入到mysql中

  • [ root@master ~]# mysql - uroot - p < /tmp/ db . dump
  • 7.1 mysql主从复制

    MySQL数据库的主从复制方案,是其自带的功能,并且主从复制并不是复制磁盘上的数据库文件,而是通过binlog日志复制到需要同步的从服务器上。

    MySQL数据库支持单向、双向、链式级联,等不同业务场景的复制。在复制的过程中,一台服务器充当主服务器(Master),接收来自用户的内容更新,而一个或多个其他的服务器充当从服务器(slave),接收来自Master上binlog文件的日志内容,解析出SQL,重新更新到Slave,使得主从服务器数据达到一致。

    主从复制的逻辑有以下几种

    一主一从,单向主从同步模式,只能在Master端写入数据

  • 利用复制功能当 Master 服务器出现问题时,我们可以人工的切换到从服务器继续提供服务,此时服务器的数据和宕机时的数据几乎完全一致。
  • 复制功能也可用作数据备份,但是如果人为的执行 drop , delete 等语句删除,那么从库的备份功能也就失效了.
  • 主从复制原理图

  • ( 1 ) master 将改变记录到二进制日志( binary log )中(这些记录叫做二进制日志事件, binary log events );
  • ( 2 ) slave master binary log events 拷贝到它的中继日志( relay log );
  • ( 3 ) slave 重做中继日志中的事件,将改变反映它自己的数据。
  • 步骤1 配置master主库

  • #查看数据库状态
  • systemctl status mariadb
  • #停mariadb
  • systemctl stop mariadb
  • #修改配置文件
  • vim / etc / my . cnf
  • #修改内容
  • #解释:server-id服务的唯一标识(主从之间都必须不同);log-bin启动二进制日志名称为mysql-bin
  • [ mysqld ]
  • server - id = 1
  • log - bin = mysql - bin
  • #重启mariadb
  • systemctl start mariadb
  • 步骤2 在master主库添加进行同步的用户

  • 1. 新建用于主从同步的用户 username ,允许登录的从库是 '%'
  • create user 'username' @ '%' identified by 'password' ;
  • 2. #题外话:如果提示密码太简单不复合策略加在前面加这句
  • mysql > set global validate_password_policy = 0 ;
  • 3. 给从库账号授权,说明给 username 从库复制的权限,在 "%" 机器上复制
  • grant replication slave on *.* to 'username' @ '%' ;
  • #检查主库创建的复制账号
  • select user , host from mysql . user ;
  • #检查授权账号的权限
  • show grants for username@ '%' ;
  • 实现对主数据库锁表只读,防止数据写入,数据复制失败
  • flush table with read lock ;
  • 4. 检查主库的状态
  • MariaDB [( none )]> show master status
  • +------------------+----------+--------------+------------------+
  • | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
  • +------------------+----------+--------------+------------------+
  • | mysql - bin . 000001 | 575 | | |
  • +------------------+----------+--------------+------------------+
  • 1 row in set ( 0.00 sec )
  • File 是二进制日志文件名, Position 是日志开始的位置。后面从库会用到 后面从库会用到 后面从库会用到!!!!!!
  • 5. 锁表后,一定要单独再打开一个 SSH 窗口,导出数据库的所有数据,
  • [ root@oldboy_python ~ 19 : 32 : 45 ]# mysqldump - uroot - p -- all - databases > /data/ all . sql
  • 6. 确保数据导出后,没有数据插入,完毕再查看主库状态
  • show master status ;
  • 7. 导出数据完毕后,解锁主库,恢复可写;
  • unlock tables ;
  • 8. 将备份导出的数据 scp Slave 数据库
  • scp / data / all . sql root@ip : /data/
  • 步骤3 配置salve从库机器

  • 1. 设置 server - id 值并关闭 binlog 功能参数
  • 数据库的 server - id 在主从复制体系内是唯一的, Slave server - id 要与主库和其他从库不同,并且注释掉 Slave binlog 参数。
  • 2. 因此修改 Slave 的/ etc / my . cnf ,写入
  • [ mysqld ]
  • server - id = 3
  • 3. 重启数据库
  • systemctl restart mariadb
  • 4. 检查 Slava 从数据库的各项参数
  • show variables like 'log_bin' ;
  • show variables like 'server_id' ;
  • 5. 恢复主库 Master 的数据导入到 Slave
  • 导入数据(注意 sql 文件的路径)
  • mysql > source / data / all . sql ;
  • #mysql -uroot -p < abc.sql
  • 6. 配置复制的参数, Slave 从库连接 Master 主库的配置
  • mysql > change master to master_host = 'x.x.x.x' ,
  • master_user = 'username' ,
  • master_password = 'password' ,
  • master_log_file = 'mysql-bin.000001' ,
  • master_log_pos = 575 ;
  • 7. 启动从库的同步开关,测试主从复制的情况
  • start slave ;
  • 8. 查看复制状态
  • show slave status\G ;
  • 步骤4 检测主从复制状态关键点

  • MariaDB [( none )]> show slave status\G
  • *************************** 1. row ***************************
  • Slave_IO_State : Waiting for master to send event
  • Master_Host : 192.168 . 119.10
  • Master_User : chaoge
  • Master_Port : 3306
  • Connect_Retry : 60
  • Master_Log_File : mysql - bin . 000001
  • Read_Master_Log_Pos : 1039
  • Relay_Log_File : slave - relay - bin . 000002
  • Relay_Log_Pos : 537
  • Relay_Master_Log_File : mysql - bin . 000001
  • Slave_IO_Running : Yes
  • Slave_SQL_Running : Yes
  • 注意此处还未配置从库的只读模式,只需在slave服务器上配置/etc/my.cnf,加上以下配置,并且在slave上创建普通用户,使用普通用户主从同步即可达到只读的效果

    如果用root用户,无法达到readonly,这是一个坑

  • [ mysqld ]
  • character - set - server = utf8
  • collation - server = utf8_general_ci
  • log - error = /var/ log / mysqld . log
  • server - id = 3
  • read - only = true
  • [ client ]
  • default - character - set = utf8
  • [ mysql ]
  • default - character - set = utf8
  • 编译安装的优势是:

  • 编译安装时可以指定扩展的module(模块),php、apache、nginx都是一样有很多第三方扩展模块,如mysql,编译安装时候,如果需要就定制存储引擎(innodb,还是MyIASM)
  • 编译安装可以统一安装路径,linux软件约定安装目录在/opt/下面
  • 软件仓库版本一般比较低,编译源码安装可以根据需求,安装最新的版本
  • 编译安装redis步骤

  • 1. 下载 redis 源码
  • wget http : //download.redis.io/releases/redis-4.0.10.tar.gz
  • 2. 解压缩
  • tar - zxf redis - 4.0 . 10.tar . gz
  • 3. 切换 redis 源码目录
  • cd redis - 4.0 . 10.tar . gz
  • 4. 编译源文件
  • 5. 编译好后, src /目录下有编译好的 redis 指令
  • 6.make install 安装到指定目录,默认在/ usr / local / bin
  • redis可执行文件

  • . /redis-benchmark / /用于进行 redis 性能测试的工具
  • ./ redis - check - dump //用于修复出问题的dump.rdb文件
  • ./ redis - cli //redis的客户端
  • ./ redis - server //redis的服务端
  • ./ redis - check - aof //用于修复出问题的AOF文件
  • ./ redis - sentinel //用于集群管理
  • 启动redis服务端

  • 启动 redis 非常简单,直接./ redis - server 就可以启动服务端了,还可以用下面的方法指定要加载的配置文件:
  • redis - server redis . conf
  • 默认情况下, redis - server 会以非 daemon 的方式来运行,且默认服务端口为 6379
  • 使用redis客户端

  • #执行客户端命令即可进入
  • ./ redis - cli
  • #测试是否连接上redis
  • 127.0 . 0.1 : 6379 > ping
  • 返回 pong 代表连接上了
  • //用set来设置key、value
  • 127.0 . 0.1 : 6379 > set name "chaoge"
  • //get获取name的值
  • 127.0 . 0.1 : 6379 > get name
  • "chaoge"
  • 8.1 redis发布订阅

    redis提供了发布(publish)订阅(subbscribe)功能

    发布订阅的命令

    发布订阅的命令

  • PUBLISH channel msg
  • 将信息 message 发送到指定的频道 channel
  • SUBSCRIBE channel [ channel ...]
  • 订阅频道,可以同时订阅多个频道
  • UNSUBSCRIBE [ channel ...]
  • 取消订阅指定的频道, 如果不指定频道,则会取消订阅所有频道
  • PSUBSCRIBE pattern [ pattern ...]
  • 订阅一个或多个符合给定模式的频道,每个模式以 * 作为匹配符,比如 it * 匹配所 有以 it 开头的频道( it . news it . blog it . tweets 等等), news .* 匹配所有 news . 开头的频道( news . it news . global . today 等等),诸如此类
  • PUNSUBSCRIBE [ pattern [ pattern ...]]
  • 退订指定的规则, 如果没有参数则会退订所有规则
  • PUBSUB subcommand [ argument [ argument ...]]
  • 查看订阅与发布系统状态
  • 注意:使用发布订阅模式实现的消息队列,当有客户端订阅 channel 后只能收到后续发布到该频道的消息,之前发送的不会缓存,必须 Provider Consumer 同时在线。
  • 窗口1,启动两个redis-cli窗口,均订阅diantai 频道(channel)

    窗口2,启动发布者向频道 diantai发送消息

  • [ root@web02 ~]# redis - cli
  • 127.0 . 0.1 : 6379 > PUBLISH diantai 'jinyewugenglaiwojia'
  • ( integer ) 2
  • 窗口3,查看订阅者的消息状态

    订阅一个或者多个符合模式的频道

    窗口1,启动两个redis-cli窗口,均订阅 wang*频道(channel)

  • 127.0 . 0.1 : 6379 > PSUBSCRIBE wang *
  • Reading messages ... ( press Ctrl - C to quit )
  • 1 ) "psubscribe"
  • 2 ) "wang*"
  • 3 ) ( integer ) 1
  • 1 ) "pmessage"
  • 2 ) "wang*"
  • 3 ) "wangbaoqiang"
  • 4 ) "jintian zhennanshou "
  • 窗口2,启动redis-cli窗口,均订阅wang*频道

  • 127.0 . 0.1 : 6379 > PSUBSCRIBE wang *
  • Reading messages ... ( press Ctrl - C to quit )
  • 1 ) "psubscribe"
  • 2 ) "wang*"
  • 3 ) ( integer ) 1
  • 1 ) "pmessage"
  • 2 ) "wang*"
  • 3 ) "wangbaoqiang"
  • 4 ) "jintian zhennanshou "
  • 窗口3,发布者消息

  • [ root@web02 ~]# redis - cli
  • 127.0 . 0.1 : 6379 > PUBLISH wangbaoqiang "jintian zhennanshou "
  • ( integer ) 2
  • 8.2 redis持久化rdb与aof

    Redis 是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题, Redis 提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失。

    RDB持久化

    redis 提供了 RDB持久化 的功能,这个功能可以将 redis 在内存中的的状态保存到硬盘中,它可以 手动执行。

    也可以再 redis.conf 中配置, 定期执行

    RDB持久化产生的RDB文件是一个 经过压缩 二进制文件 ,这个文件被保存在硬盘中,redis可以通过这个文件还原数据库当时的状态。

  • RDB (持久化)
  • 内存数据保存到磁盘
  • 在指定的时间间隔内生成数据集的时间点快照( point - in - time snapshot
  • 优点:速度快,适合做备份,主从复制就是基于 RDB 持久化功能实现
  • rdb 通过再 redis 中使用 save 命令触发 rdb
  • rdb 配置参数:
  • dir / data / 6379 /
  • dbfilename dbmp . rdb
  • 每过 900 1 个操作就进行持久化
  • save 900 1 个修改类的操作
  • save 300 10 个操作
  • save 60 10000 个操作
  • save 900 1
  • save 300 10
  • save 60 10000
  • redis持久化之RDB实践

    1.启动redis服务端,准备配置文件

  • daemonize yes
  • port 6379
  • logfile / data / 6379 / redis . log
  • dir / data / 6379 #定义持久化文件存储位置
  • dbfilename dbmp . rdb #rdb持久化文件
  • bind 10.0 . 0.10 127.0 . 0.1 #redis绑定地址
  • requirepass redhat #redis登录密码
  • save 900 1 #rdb机制 每900秒 有1个修改记录
  • save 300 10 #每300秒 10个修改记录
  • save 60 10000 #每60秒内 10000修改记录
  • 2.启动redis服务端

    3.登录redis设置一个key

  • redis - cli - a redhat
  • 4.此时检查目录,/data/6379底下没有dbmp.rdb文件

    5.通过save触发持久化,将数据写入RDB文件

  • 127.0 . 0.1 : 6379 > set age 18
  • 127.0 . 0.1 : 6379 > save
  • redis持久化之AOF

    AOF(append-only log file)
    记录服务器执行的所有变更操作命令(例如set del等),并在服务器启动时,通过重新执行这些命令来还原数据集
    AOF 文件中的命令全部以redis协议的格式保存,新命令追加到文件末尾。
    优点:最大程序保证数据不丢
    缺点:日志记录非常大

  • redis - client 写入数据 > redis - server 同步命令 > AOF 文件
  • AOF 持久化配置,两条参数
  • appendonly yes
  • appendfsync always 总是修改类的操作
  • everysec 每秒做一次持久化
  • no 依赖于系统自带的缓存大小机制
  • 1.准备aof配置文件 redis.conf

  • daemonize yes
  • port 6379
  • logfile / data / 6379 / redis . log
  • dir / data / 6379
  • dbfilename dbmp . rdb
  • requirepass redhat
  • save 900 1
  • save 300 10
  • save 60 10000
  • appendonly yes
  • appendfsync everysec
  • 2.启动redis服务

  • redis - server / etc / redis . conf
  • 3.检查redis数据目录/data/6379/是否产生了aof文件

  • [ root@web02 6379 ]# ls
  • appendonly . aof dbmp . rdb redis . log
  • 4.登录redis-cli,写入数据,实时检查aof文件信息

  • [ root@web02 6379 ]# tail - f appendonly . aof
  • 5.设置新key,检查aof信息,然后关闭redis,检查数据是否持久化

  • redis - cli - a redhat shutdown
  • redis - server / etc / redis . conf
  • redis - cli - a redhat
  • redis 持久化方式有哪些?有什么区别?

    rdb:基于快照的持久化,速度更快,一般用作备份,主从复制也是依赖于rdb持久化功能

    aof:以追加的方式记录redis操作日志的文件。可以最大程度的保证redis数据安全,类似于mysql的binlog

    RDB持久化切换AOF持久化

    确保redis版本在2.2以上

  • [ root@pyyuc / data 22 : 23 : 30 ]# redis - server - v
  • Redis server v = 4.0 . 10 sha = 00000000 : 0 malloc = jemalloc - 4.0 . 3 bits = 64 build = 64cb6afcf41664c
  • 本文在redis4.0中,通过config set命令,达到不重启redis服务,从RDB持久化切换为AOF

    实验环境准备

    redis.conf服务端配置文件

  • daemonize yes
  • port 6379
  • logfile / data / 6379 / redis . log
  • dir / data / 6379
  • dbfilename dbmp . rdb
  • save 900 1 #rdb机制 每900秒 有1个修改记录
  • save 300 10 #每300秒 10个修改记录
  • save 60 10000 #每60秒内 10000修改记录
  • 启动redis服务端

  • redis - server redis . conf
  • 登录redis-cli插入数据,手动持久化

  • 127.0 . 0.1 : 6379 > set name chaoge
  • 127.0 . 0.1 : 6379 > set age 18
  • 127.0 . 0.1 : 6379 > set addr shahe
  • 127.0 . 0.1 : 6379 > save
  • 检查RDB文件

  • [ root@pyyuc / data 22 : 34 : 16 ]# ls 6379 /
  • dbmp . rdb redis . log
  • 备份这个rdb文件,保证数据安全

  • [ root@pyyuc / data / 6379 22 : 35 : 38 ]# cp dbmp . rdb / opt /
  • 执行命令,开启AOF持久化

  • 127.0 . 0.1 : 6379 > CONFIG set appendonly yes #开启AOF功能
  • 127.0 . 0.1 : 6379 > CONFIG SET save "" #关闭RDB功能
  • 确保数据库的key数量正确

  • 127.0 . 0.1 : 6379 > keys *
  • 1 ) "addr"
  • 2 ) "age"
  • 3 ) "name"
  • 确保插入新的key,AOF文件会记录

  • 127.0 . 0.1 : 6379 > set title golang
  • 此时RDB已经正确切换AOF,注意还得修改redis.conf添加AOF设置,不然重启后,通过config set的配置将丢失

    8.3 redis主从同步

  • 从服务器向主服务器发送 SYNC 命令。
  • 接到 SYNC 命令的主服务器会调用BGSAVE 命令,创建一个 RDB 文件,并使用缓冲区记录接下来执行的所有写命令。
  • 当主服务器执行完 BGSAVE 命令时,它会向从服务器发送 RDB 文件,而从服务器则会接收并载入这个文件。
  • 主服务器将缓冲区储存的所有写命令发送给从服务器执行。
    -——————
    1、在开启主从复制的时候,使用的是RDB方式的,同步主从数据的
    2、同步开始之后,通过主库命令传播的方式,主动的复制方式实现
    3、2.8以后实现PSYNC的机制,实现断线重连
  • redis主从同步配置

    步骤一、准备一主两从的数据库实例

    主节点:6380

    从节点:6381、6382

    6380.conf

  • 1 、环境:
  • 准备两个或两个以上 redis 实例
  • mkdir / data / 638 { 0. . 2 } #创建6380 6381 6382文件夹
  • 配置文件示例:
  • vim / data / 6380 / redis . conf
  • port 6380
  • daemonize yes
  • pidfile / data / 6380 / redis . pid
  • loglevel notice
  • logfile "/data/6380/redis.log"
  • dbfilename dump . rdb
  • dir / data / 6380
  • protected - mode no
  • 6381.conf

  • vim / data / 6381 / redis . conf
  • port 6381
  • daemonize yes
  • pidfile / data / 6381 / redis . pid
  • loglevel notice
  • logfile "/data/6381/redis.log"
  • dbfilename dump . rdb
  • dir / data / 6381
  • protected - mode no
  • 6382.conf

  • port 6382
  • daemonize yes
  • pidfile / data / 6382 / redis . pid
  • loglevel notice
  • logfile "/data/6382/redis.log"
  • dbfilename dump . rdb
  • dir / data / 6382
  • protected - mode no
  • 启动三个redis实例

  • redis - server / data / 6380 / redis . conf
  • redis - server / data / 6381 / redis . conf
  • redis - server / data / 6382 / redis . conf
  • 步骤二、配置主从同步

    6381/6382命令行

    redis-cli -p 6381
    SLAVEOF 127.0.0.1 6380 #指明主的地址

    redis-cli -p 6382
    SLAVEOF 127.0.0.1 6380 #指明主的地址

    检查主从状态

  • 127.0 . 0.1 : 6382 > info replication
  • 127.0 . 0.1 : 6381 > info replication
  • 127.0 . 0.1 : 6380 > info replication
  • 测试写入数据,主库写入数据,检查从库数据

  • 127.0 . 0.1 : 6380 > set name chaoge
  • 127.0 . 0.1 : 6381 > get name
  • 手动进行主从复制故障切换

  • #关闭主库6380
  • redis - cli - p 6380
  • shutdown
  • 检查从库主从信息,此时master_link_status:down

  • redis - cli - p 6381
  • info replication
  • redis - cli - p 6382
  • info replication
  • 既然主库挂了,我想要在6381 6382之间选一个新的主库

    1.关闭6381的从库身份

  • redis - cli - p 6381
  • info replication
  • slaveof no one
  • 2.将6382设为6381的从库

  • 6382 连接到 6381
  • [ root@db03 ~]# redis - cli - p 6382
  • 127.0 . 0.1 : 6382 > SLAVEOF no one
  • 127.0 . 0.1 : 6382 > SLAVEOF 127.0 . 0.1 6381
  • 3.检查6382,6381的主从信息

    8.4 redis哨兵

    redis-Sentinel

  • Redis - Sentinel redis 官方推荐的高可用性解决方案,
  • 当用 redis master - slave 的高可用时,如果 master 本身宕机, redis 本身或者客户端都没有实现主从切换的功能。
  • redis - sentinel 就是一个独立运行的进程,用于监控多个 master - slave 集群,
  • 自动发现 master 宕机,进行自动切换 slave > master
  • sentinel主要功能如下:

  • 不时的监控redis是否良好运行,如果节点不可达就会对节点进行下线标识
  • 如果被标识的是主节点,sentinel就会和其他的sentinel节点“协商”,如果其他节点也人为主节点不可达,就会选举一个sentinel节点来完成自动故障转义
  • 在master-slave进行切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换
  • Redis-sentinel工作机制

  • 每个 Sentinel 以每秒钟一次的频率向它所知的 Master Slave 以及其他 Sentinel 实例发送一个 PING 命令
  • 如果一个实例( instance )距离最后一次有效回复 PING 命令的时间超过 down - after - milliseconds 选项所指定的值, 则这个实例会被 Sentinel 标记为主观下线。
  • 如果一个 Master 被标记为主观下线,则正在监视这个 Master 的所有 Sentinel 要以每秒一次的频率确认 Master 的确进入了主观下线状态。
  • 当有足够数量的 Sentinel (大于等于配置文件指定的值)在指定的时间范围内确认 Master 的确进入了主观下线状态, Master 会被标记为客观下线
  • 在一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有 Master Slave 发送 INFO 命令
  • Master Sentinel 标记为客观下线时, Sentinel 向下线的 Master 的所有 Slave 发送 INFO 命令的频率会从 10 秒一次改为每秒一次
  • 若没有足够数量的 Sentinel 同意 Master 已经下线, Master 的客观下线状态就会被移除。
  • Master 重新向 Sentinel PING 命令返回有效回复, Master 的主观下线状态就会被移除。
  • 主观下线和客观下线
  • 主观下线: Subjectively Down ,简称 SDOWN ,指的是当前 Sentinel 实例对某个 redis 服务器做出的下线判断。
  • 客观下线: Objectively Down 简称 ODOWN ,指的是多个 Sentinel 实例在对 Master Server 做出 SDOWN 判断,并且通过 SENTINEL is - master - down - by - addr 命令互相交流之后,得出的 Master Server 下线判断,然后开启 failover .
  • SDOWN 适合于 Master Slave ,只要一个 Sentinel 发现 Master 进入了 ODOWN 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对下线的主服务器执行自动故障迁移操作。
  • ODOWN 只适用于 Master ,对于 Slave Redis 实例, Sentinel 在将它们判断为下线前不需要进行协商, 所以 Slave Sentinel 永远不会达到 ODOWN
  • redis主从复制背景问题

    Redis 主从复制可将主节点数据同步给从节点,从节点此时有两个作用:

  • 一旦主节点宕机,从节点作为主节点的备份可以随时顶上来。
  • 扩展主节点的读能力,分担主节点读压力。
  • 但是问题是:

  • 一旦主节点宕机,从节点上位,那么需要人为修改所有应用方的主节点地址(改为新的master地址),还需要命令所有从节点复制新的主节点
  • 那么这个问题,redis-sentinel就可以解决了

    主从复制架构图

    redis sentinel架构图

    redis的一个进程,但是不存储数据,只是监控redis

    安装配置redis哨兵

    本实验是在测试环境下,考虑到学生机器较弱,因此只准备一台linux服务器用作环境!!

    服务器环境,一台即可完成操作

    主节点master的redis-6379.conf

  • port 6379
  • daemonize yes
  • logfile "6379.log"
  • dbfilename "dump-6379.rdb"
  • dir "/var/redis/data/"
  • 从节点slave的redis-6380.conf

  • port 6380
  • daemonize yes
  • logfile "6380.log"
  • dbfilename "dump-6380.rdb"
  • dir "/var/redis/data/"
  • slaveof 127.0 . 0.1 6379 // 从属主节点
  • 从节点slave的redis-6381.conf

  • port 6381
  • daemonize yes
  • logfile "6380.log"
  • dbfilename "dump-6380.rdb"
  • dir "/var/redis/data/"
  • slaveof 127.0 . 0.1 6379 // 从属主节点
  • 启动redis主节点

  • redis - server / etc / redis - 6379.conf
  • 测试redis主节点是否通信

  • redis - cli ping
  • 启动两slave节点

    还记得上面超哥的截图吗?总体redis配置文件如下,6379为master,6380和6381为slave

  • - rw - r -- r -- 1 root root 145 Nov 7 17 : 44 / etc / redis - 6379.conf #这个为主,port是6379
  • - rw - r -- r -- 1 root root 93 Nov 7 17 : 42 / etc / redis - 6380.conf # 这个是从,port6380,并且得加上新的参数slaveof
  • - rw - r -- r -- 1 root root 115 Nov 7 17 : 42 / etc / redis - 6381.conf # 这个是从,port6381,并且得加上新的参数slaveof
  • redis - server / etc / redis - 6380.conf
  • redis - server / etc / redis - 6381.conf
  • 验证从节点的redis服务

  • [ root@master ~] $redis - cli - p 6380 ping
  • [ root@master ~] $redis - cli - p 6381 ping
  • 检测主从关系

    在主节点上查看主从通信关系

  • [ root@master ~]# redis - cli - p 6379 info replication
  • # Replication
  • role : master
  • connected_slaves : 2
  • slave0 : ip = 192.168 . 119.10 , port = 6380 , state = online , offset = 407 , lag = 0
  • slave1 : ip = 192.168 . 119.10 , port = 6381 , state = online , offset = 407 , lag = 0
  • master_repl_offset : 407
  • repl_backlog_active : 1
  • repl_backlog_size : 1048576
  • repl_backlog_first_byte_offset : 2
  • repl_backlog_histlen : 406
  • 在从节点上查看主从关系(6380、6379)

  • [ root@slave 192.168 . 119.11 ~] $redis - cli - p 6380 info replication
  • # Replication
  • role : slave
  • master_host : 192.168 . 119.10
  • master_port : 6379
  • master_link_status : up
  • master_last_io_seconds_ago : 3
  • master_sync_in_progress : 0
  • slave_repl_offset : 505
  • slave_priority : 100
  • slave_read_only : 1
  • connected_slaves : 0
  • master_repl_offset : 0
  • repl_backlog_active : 0
  • repl_backlog_size : 1048576
  • repl_backlog_first_byte_offset : 0
  • repl_backlog_histlen : 0
  • 此时可以在master上写入数据,在slave上查看数据,此时主从复制配置完

    配置redis sentinel环境

    实验的环境是单独一台linux

  • [ root@master tmp ]# ll / etc / redis -*
  • - rw - r -- r -- 1 root root 145 Nov 7 17 : 44 / etc / redis - 6379.conf
  • - rw - r -- r -- 1 root root 93 Nov 7 17 : 42 / etc / redis - 6380.conf
  • - rw - r -- r -- 1 root root 115 Nov 7 17 : 42 / etc / redis - 6381.conf
  • - rw - r -- r -- 1 root root 556 Nov 7 17 : 42 / etc / redis - sentinel - 26379.conf
  • - rw - r -- r -- 1 root root 556 Nov 7 17 : 42 / etc / redis - sentinel - 26380.conf
  • - rw - r -- r -- 1 root root 556 Nov 7 17 : 42 / etc / redis - sentinel - 26381.conf
  • redis-sentinel-26379.conf配置文件写入如下信息

  • // Sentinel节点的端口
  • port 26379
  • dir / var / redis / data /
  • logfile "26379.log"
  • // 当前Sentinel节点监控 192.168.119.10:6379 这个主节点
  • // 2代表判断主节点失败至少需要2个Sentinel节点节点同意
  • // mymaster是主节点的别名
  • sentinel monitor mymaster 192.168 . 119.10 6379 2
  • //每个Sentinel节点都要定期PING命令来判断Redis数据节点和其余Sentinel节点是否可达,如果超过30000毫秒30s且没有回复,则判定不可达
  • sentinel down - after - milliseconds mymaster 30000
  • //当Sentinel节点集合对主节点故障判定达成一致时,Sentinel领导者节点会做故障转移操作,选出新的主节点,
  • 原来的从节点会向新的主节点发起复制操作,限制每次向新的主节点发起复制操作的从节点个数为 1
  • sentinel parallel - syncs mymaster 1
  • //故障转移超时时间为180000毫秒
  • sentinel failover - timeout mymaster 180000
  • redis - sentinel - 26380.conf
  • redis - sentinel - 26381.conf 的配置仅仅差异是 port (端口)的不同。
  • 然后启动三个sentinel哨兵

  • redis - sentinel / etc / redis - sentinel - 26379.conf
  • redis - sentinel / etc / redis - sentinel - 26380.conf
  • redis - sentinel / etc / redis - sentinel - 26381.conf
  • 此时查看哨兵是否成功通信

  • [ root@master ~]# redis - cli - p 26379 info sentinel
  • # Sentinel
  • sentinel_masters : 1
  • sentinel_tilt : 0
  • sentinel_running_scripts : 0
  • sentinel_scripts_queue_length : 0
  • sentinel_simulate_failure_flags : 0
  • master0 : name = mymaster , status = ok , address = 192.168 . 119.10 : 6379 , slaves = 2 , sentinels = 3
  • #看到最后一条信息正确即成功了哨兵,哨兵主节点名字叫做mymaster,状态ok,监控地址是192.168.119.10:6379,有两个从节点,3个哨兵
  • redis高可用故障实验

  • 杀掉主节点的redis进程6379端口,观察从节点是否会进行新的master选举,进行切换
  • 重新恢复旧的“master”节点,查看此时的redis身份

    首先查看三个redis的进程状态

  • role : master
  • connected_slaves : 2
  • slave0 : ip = 127.0 . 0.1 , port = 6381 , state = online , offset = 54386 , lag = 0
  • slave1 : ip = 127.0 . 0.1 , port = 6379 , state = online , offset = 54253 , lag = 0
  • [ root@master tmp ]# redis - cli - p 6379 info replication
  • # Replication
  • role : slave
  • master_host : 127.0 . 0.1
  • master_port : 6380
  • 此时,干掉master!!!然后等待其他两个节点是否能自动被哨兵sentienl,切换为master节点

  • ps - ef | grep 6380 #干掉master进程
  • 此时查看两个slave的状态

    精髓就是查看一个参数

  • master_link_down_since_seconds : 13
  • 稍等片刻之后,发现slave节点成为master节点!!

  • [ root@master tmp ]# redis - cli - p 6379 info replication
  • # Replication
  • role : master
  • connected_slaves : 1
  • slave0 : ip = 127.0 . 0.1 , port = 6381 , state = online , offset = 41814 , lag = 1
  • 大功告成!!

    8.5 redis-cluster

    为什么要用redis-cluster

  • redis 官方生成可以达到 10 万/每秒,每秒执行 10 万条命令
  • 假如业务需要每秒 100 万的命令执行呢?
  • 数据量太大

    一台服务器内存正常是16~256G,假如你的业务需要500G内存,你怎么办?

    新浪微博作为世界上最大的redis存储,就超过1TB的数据,去哪买这么大的内存条?

    解决方案如下

  • 配置一个超级牛逼的计算机,超大内存,超强cpu,但是问题是。。。。
  • 2.正确的应该是考虑分布式,加机器,把数据分到不同的位置,分摊集中式的压力, 一堆机器做一件事

    客户端分片

  • redis 实例集群主要思想是将 redis 数据的 key 进行散列,通过 hash 函数特定的 key 会映射到指定的 redis 节点上
  • 数据分布原理图

    分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。

    常见的分区规则有哈希分区和顺序分区。 Redis Cluster 采用哈希分区规则,因此接下来会讨论哈希分区规则。

  • 节点取余分区
  • 一致性哈希分区
  • 虚拟槽分区(redis-cluster采用的方式)
  • 例如按照节点取余的方式,分三个节点

    1~100的数据对3取余,可以分为三类

    那么同样的分4个节点就是hash(key)%4

    节点取余的优点是简单,客户端分片直接是哈希+取余

    虚拟槽分区

    Redis Cluster 采用虚拟槽分区

    虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。

    Redis Cluster槽的范围是0 ~ 16383。

    槽是集群内数据管理和迁移的基本单位。 采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,

    每个节点负责一定数量的槽。

    如何搭建redis-cluster

    搭建集群分为几部

  • 准备节点(几匹马儿)
  • 节点通信(几匹马儿分配主从)
  • 分配槽位给节点(slot分配给马儿)
  • redis-cluster集群架构

  • 多个服务端,负责读写,彼此通信, redis 指定了 16384 个槽。
  • 多匹马儿,负责运输数据,马儿分配 16384 个槽位,管理数据。
  • ruby 的脚本自动就把分配槽位这事做了
  • 官方提供通过ruby语言的脚本一键安装

    步骤一、通过配置,redis.conf开启redis-cluster

  • port 7000
  • daemonize yes
  • dir "/opt/redis/data"
  • logfile "7000.log"
  • dbfilename "dump-7000.rdb"
  • cluster - enabled yes #开启集群模式
  • cluster - config - file nodes - 7000.conf #集群内部的配置文件
  • cluster - require - full - coverage no #redis cluster需要16384个slot都正常的时候才能对外提供服务,换句话说,只要任何一个slot异常那么整个cluster不对外提供服务。 因此生产环境一般为no
  • redis支持多实例的功能,我们在单机演示集群搭建,需要6个实例,三个是主节点,三个是从节点,数量为6个节点才能保证高可用的集群。

    每个节点仅仅是端口运行的不同!

  • [ root@yugo / opt / redis / config 17 : 12 : 30 ]# ls
  • redis - 7000.conf redis - 7002.conf redis - 7004.conf
  • redis - 7001.conf redis - 7003.conf redis - 7005.conf
  • #确保每个配置文件中的端口修改!!
  • 步骤二、运行redis实例

    创建6个节点的redis实例

  • 1855 2018 - 10 - 24 15 : 46 : 01 redis - server redis - 7000.conf
  • 1856 2018 - 10 - 24 15 : 46 : 13 redis - server redis - 7001.conf
  • 1857 2018 - 10 - 24 15 : 46 : 16 redis - server redis - 7002.conf
  • 1858 2018 - 10 - 24 15 : 46 : 18 redis - server redis - 7003.conf
  • 1859 2018 - 10 - 24 15 : 46 : 20 redis - server redis - 7004.conf
  • 1860 2018 - 10 - 24 15 : 46 : 23 redis - server redis - 7005.conf
  • redis - server redis - 7000.conf
  • redis - server redis - 7001.conf
  • redis - server redis - 7002.conf
  • redis - server redis - 7003.conf
  • redis - server redis - 7004.conf
  • redis - server redis - 7005.conf
  • 步骤3、开启redis-cluster

  • 下载、编译、安装Ruby
  • 安装rubygem redis
  • 安装redis-trib.rb命令
  • 第一步、安装ruby

  • #下载ruby源码包
  • wget https : //cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz
  • #解压缩ruby源码包
  • tar - zxvf ruby - 2.3 . 1.tar . gz
  • #编译且安装
  • ./ configure -- prefix = /opt/ ruby /
  • make && make install
  • 第二步、配置ruby环境变量

  • vim / etc / profile
  • 写入如下配置
  • PATH = $PATH : /opt/ ruby / bin
  • 第三步、安装ruby操作redis包

  • wget http : //rubygems.org/downloads/redis-3.3.0.gem
  • gem install - l redis - 3.3 . 0.gem
  • 第四部、安装redis-trib.rb命令

  • [ root@yugo / opt / redis / src 18 : 38 : 13 ]# cp / opt / redis / src / redis - trib . rb / usr / local / bin /
  • 一键开启redis-cluster集群

  • #每个主节点,有一个从节点,代表--replicas 1
  • redis - trib . rb create -- replicas 1 127.0 . 0.1 : 7000 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
  • #集群自动分配主从关系 7000、7001、7002为 7003、7004、7005 主动关系
  • 查看集群状态

  • redis - cli - p 7000 cluster info
  • redis - cli - p 7000 cluster nodes #等同于查看nodes-7000.conf文件节点信息
  • 集群主节点状态
  • redis - cli - p 7000 cluster nodes | grep master
  • 集群从节点状态
  • redis - cli - p 7000 cluster nodes | grep slave
  • 写入redis-cluster集群数据

    安装完毕后,检查集群状态

  • [ root@yugo / opt / redis / src 18 : 42 : 14 ]# redis - cli - p 7000 cluster info
  • cluster_state : ok
  • cluster_slots_assigned : 16384
  • cluster_slots_ok : 16384
  • cluster_slots_pfail : 0
  • cluster_slots_fail : 0
  • cluster_known_nodes : 6
  • cluster_size : 3
  • cluster_current_epoch : 6
  • cluster_my_epoch : 1
  • cluster_stats_messages_ping_sent : 10468
  • cluster_stats_messages_pong_sent : 10558
  • cluster_stats_messages_sent : 21026
  • cluster_stats_messages_ping_received : 10553
  • cluster_stats_messages_pong_received : 10468
  • cluster_stats_messages_meet_received : 5
  • cluster_stats_messages_received : 21026
  • 测试写入集群数据,登录集群必须使用redis-cli -c -p 7000必须加上-c参数

  • 127.0 . 0.1 : 7000 > set name chao
  • -> Redirected to slot [ 5798 ] located at 127.0 . 0.1 : 7001
  • 127.0 . 0.1 : 7001 > exit
  • [ root@yugo / opt / redis / src 18 : 46 : 07 ]# redis - cli - c - p 7000
  • 127.0 . 0.1 : 7000 > ping
  • 127.0 . 0.1 : 7000 > keys *
  • ( empty list or set )
  • 127.0 . 0.1 : 7000 > get name
  • -> Redirected to slot [ 5798 ] located at 127.0 . 0.1 : 7001
  • "chao"
  • 8.6 redis-python api

  • 1 、对 redis 的单实例进行连接操作
  • python3
  • >>> import redis
  • >>> r = redis . StrictRedis ( host = 'localhost' , port = 6379 , db = 0 , password = 'root' )
  • >>> r . set ( 'lufei' , 'guojialei' )
  • >>> r . get ( 'lufei' )
  • 'bar'
  • --------------------
  • 2 sentinel 集群连接并操作
  • [ root@db01 ~]# redis - server / data / 6380 / redis . conf
  • [ root@db01 ~]# redis - server / data / 6381 / redis . conf
  • [ root@db01 ~]# redis - server / data / 6382 / redis . conf
  • [ root@db01 ~]# redis - sentinel / data / 26380 / sentinel . conf &
  • --------------------------------
  • ## 导入redis sentinel包
  • >>> from redis . sentinel import Sentinel
  • ##指定sentinel的地址和端口号
  • >>> sentinel = Sentinel ([( 'localhost' , 26380 )], socket_timeout = 0.1 )
  • ##测试,获取以下主库和从库的信息
  • >>> sentinel . discover_master ( 'mymaster' )
  • >>> sentinel . discover_slaves ( 'mymaster' )
  • ##配置读写分离
  • >>> master = sentinel . master_for ( 'mymaster' , socket_timeout = 0.1 )
  • >>> slave = sentinel . slave_for ( 'mymaster' , socket_timeout = 0.1 )
  • ###读写分离测试 key
  • >>> master . set ( 'oldboy' , '123' )
  • >>> slave . get ( 'oldboy' )
  • '123'
  • ----------------------
  • redis cluster 的连接并操作( python2 . 7.2 以上版本才支持 redis cluster ,我们选择的是 3.5
  • https : //github.com/Grokzen/redis-py-cluster
  • 3 python 连接 rediscluster 集群测试
  • python3
  • >>> from rediscluster import StrictRedisCluster
  • >>> startup_nodes = [{ "host" : "127.0.0.1" , "port" : "7000" }]
  • ### Note: decode_responses must be set to True when used with python3
  • >>> rc = StrictRedisCluster ( startup_nodes = startup_nodes , decode_responses = True )
  • >>> rc . set ( "foo" , "bar" )
  • 'bar'
  • 想必我们大多数人都是通过访问网站而开始接触互联网的吧。我们平时访问的网站服务 就是 Web 网络服务,一般是指允许用户通过浏览器访问到互联网中各种资源的服务。

    Web 网络服务是一种被动访问的服务程序,即只有接收到互联网中其他主机发出的 请求后才会响应,最终用于提供服务程序的 Web 服务器会通过 HTTP(超文本传输协议)或 HTTPS(安全超文本传输协议)把请求的内容传送给用户。

    目前能够提供 Web 网络服务的程序有 IIS、Nginx 和 Apache 等。其中,IIS(Internet Information Services,互联网信息服务)是 Windows 系统中默认的 Web 服务程序

    2004 年 10 月 4 日,为俄罗斯知名门户站点而开发的 Web 服务程序 Nginx 横空出世。 Nginx 程序作为一款轻量级的网站服务软件,因其稳定性和丰富的功能而快速占领服务器市 场,但 Nginx 最被认可的还当是系统资源消耗低且并发能力强,因此得到了国内诸如新浪、 网易、腾讯等门户站的青睐。

  • web 服务器( nginx ):接收 HTTP 请求(例如 www . pythonav . cn / xiaocang . jpg )并返回数据
  • web 框架( django flask ):开发 web 应用程序,处理接收到的数据
  • nginx介绍

  • nginx 是一个开源的,支持高性能,高并发的 www 服务和代理服务软件。它是一个俄罗斯人 lgor sysoev 开发的,作者将源代码开源出来供全球使用。
  • nginx 比它大哥 apache 性能改进许多, nginx 占用的系统资源更少,支持更高的并发连接,有更高的访问效率。
  • nginx 不但是一个优秀的 web 服务软件,还可以作为反向代理,负载均衡,以及缓存服务使用。
  • 安装更为简单,方便,灵活。
  • 支持高并发,能支持几万并发连接
  • 资源消耗少,在 3 万并发连接下开启 10 nginx 线程消耗的内存不到 200M
  • 可以做 http 反向代理和负载均衡
  • 支持异步网络 i / o 事件模型 epoll
  • Tengine

    Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。

    安装配置nginx

    安装nginx前的依赖环境解决

  • #执行第一条语句即可
  • yum install gcc patch libffi - devel python - devel zlib - devel bzip2 - devel openssl - devel ncurses - devel sqlite - devel readline - devel tk - devel gdbm - devel db4 - devel libpcap - devel xz - devel openssl openssl - devel - y
  • #依赖简单介绍
  • 一. gcc 安装
  • 安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,则需要安装:
  • yum install gcc - c ++
  • 二. PCRE pcre - devel 安装
  • PCRE ( Perl Compatible Regular Expressions ) 是一个 Perl 库,包括 perl 兼容的正则表达式库。 nginx http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库, pcre - devel 是使用 pcre 开发的一个二次开发库。 nginx 也需要此库。命令:
  • yum install - y pcre pcre - devel
  • 三. zlib 安装
  • zlib 库提供了很多种压缩和解压缩的方式, nginx 使用 zlib http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。
  • yum install - y zlib zlib - devel
  • 四. OpenSSL 安装
  • OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。
  • nginx 不仅支持 http 协议,还支持 https (即在 ssl 协议上传输 http ),所以需要在 Centos 安装 OpenSSL 库。
  • 编译安装nginx

  • 1. 下载源码包
  • wget - c https : //nginx.org/download/nginx-1.12.0.tar.gz
  • 2. 解压缩源码
  • tar - zxvf nginx - 1.12 . 0.tar . gz
  • 3. 配置,编译安装 开启 nginx 状态监测功能
  • ./ configure -- prefix = /opt/ nginx112 /
  • make && make install
  • 4. 启动 nginx ,进入 sbin 目录,找到 nginx 启动命令
  • cd sbin
  • ./ nginx #启动
  • ./ nginx - s stop #关闭
  • ./ nginx - s reload #重新加载
  • 5. 修改 PATH
  • PATH = $PATH : /opt/ nginx112 /
  • nginx软件目录

  • [ root@oldboy_python / opt / nginx1 - 12 11 : 44 : 02 ]# ls
  • client_body_temp conf fastcgi_temp html logs proxy_temp sbin scgi_temp static uwsgi_temp
  • conf 存放nginx所有配置文件的目录,主要nginx.conf
  • html 存放nginx默认站点的目录,如index.html、error.html等
  • logs 存放nginx默认日志的目录,如error.log access.log
  • sbin 存放nginx主命令的目录,sbin/nginx
  • Nginx主配置文件 /etc/nginx/nginx.conf 是一个纯文本类型的文件,整个配置文件是以区块的形式组织的。一般,每个区块以一对大括号 {} 来表示开始与结束。

  • CoreModule 核心模块
  • user www ; #Nginx进程所使用的用户
  • worker_processes 1 ; #Nginx运行的work进程数量(建议与CPU数量一致或auto)
  • error_log / log / nginx / error . log #Nginx错误日志存放路径
  • pid / var / run / nginx . pid #Nginx服务运行后产生的pid进程号
  • events 事件模块
  • events {
  • worker_connections //每个worker进程支持的最大连接数
  • use epool ; //事件驱动模型, epoll默认
  • http 内核模块
  • //公共的配置定义在http{}
  • http { //http层开始
  • //使用Server配置网站, 每个Server{}代表一个网站(简称虚拟主机)
  • 'server' {
  • listen 80 ; //监听端口, 默认80
  • server_name localhost ; //提供服务的域名或主机名
  • access_log host . access . log //访问日志
  • //控制网站访问路径
  • 'location' / {
  • root / usr / share / nginx / html ; //存放网站代码路径
  • index index . html index . htm ; //服务器返回的默认页面文件
  • //指定错误代码, 统一定义错误页面, 错误代码重定向到新的Locaiton
  • error_page 500 502 503 504 / 50x . html ;
  • //第二个虚拟主机配置
  • 'server' {
  • include / etc / nginx / conf . d /*.conf; //包含/etc/nginx/conf.d/目录下所有以.conf结尾的文件
  • } //http层结束
  • 部署nginx站点

    nginx默认站点是Nginx目录下的html文件夹,这里可以从nginx.conf中查到

  • location /{
  • root html ; #这里是默认的站点html文件夹,也就是 /opt/nginx1-12/html/文件夹下的内容
  • index index . html index . htm ; #站点首页文件名是index.html
  • 如果要部署网站业务数据,只需要把开发好的程序全放到html目录下即可

  • [ root@oldboy_python / tmp 11 : 34 : 52 ]# ls / opt / nginx1 - 12 / html /
  • index . html jssts . jpeg lhy . mp4 man . jpg wget - log
  • 因此只需要通过域名/资源,即可访问

  • http : //www.pyyuc.cn/man.jpg
  • Nginx多个虚拟主机

    如果每台linux服务器只运行了一个小网站,那么人气低,流量小的草根站长需要承担高额的服务器租赁费,也造成了硬件资源浪费。

    虚拟主机就是将一台服务器分割成多个“虚拟服务器”,每个站点使用各自的硬盘空间,由于省资源,省钱,众多网站都使用虚拟主机来部署网站。

  • 虚拟主机的概念就是在 web 服务里的一个独立的网站站点,这个站点对应独立的域名( IP ),具有独立的程序和资源目录,可以独立的对外提供服务。
  • 这个独立的站点配置是在 nginx . conf 中使用 server {}代码块标签来表示一个虚拟主机。
  • Nginx 支持多个 server {}标签,即支持多个虚拟主机站点。
  • 虚拟主机类型

  • 基于域名的虚拟主机
  • 通过不同的域名区分不同的虚拟主机,是企业应用最广的虚拟主机。
  • 基于端口的虚拟主机
  • 通过不同的端口来区分不同的虚拟主机,一般用作企业内部网站,不对外直接提供服务的后台,例如 www . pythonav . cn : 9000
  • 基于 IP 的虚拟主机
  • 通过不同的 IP 区分不同的虚拟主机,此类比较少见,一般业务需要多 IP 的常见都会在负载均衡中绑定 VIP
  • nginx可以自动识别用户请求的域名,根据不同的域名请求服务器传输不同的内容,只需要保证服务器上有一个可用的ip地址,配置好dns解析服务。

    /etc/hosts是linux系统中本地dns解析的配置文件,同样可以达到域名访问效果

    修改nginx.conf

  • egrep - v '#|^$' / opt / nginx1 - 12 / conf / nginx . conf
  • #配置文件内容如下
  • worker_processes 1 ;
  • events {
  • worker_connections 1024 ;
  • http {
  • include mime . types ;
  • default_type application / octet - stream ;
  • log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  • '$status $body_bytes_sent "$http_referer" '
  • '"$http_user_agent" "$http_x_forwarded_for"' ;
  • access_log logs / access . log main ;
  • sendfile on ;
  • keepalive_timeout 65 ;
  • #虚拟主机1
  • server {
  • listen 80 ;
  • server_name www . pyyuc . cn ;
  • location /{
  • root html / pyyuc ;
  • index index . html index . htm ;
  • #虚拟主机2
  • server {
  • listen 80 ;
  • server_name www . pythonav . cn ;
  • location /{
  • root html / pythonav ;
  • index index . html index . htm ;
  • [ root@oldboy_python / opt / nginx1 - 12 14 : 52 : 12 ]# curl www . pythonav . cn
  • < meta charset = utf8 >我是 pythonav ,未成年禁止入内
  • [ root@oldboy_python / opt / nginx1 - 12 14 : 52 : 40 ]# curl www . pyyuc . cn
  • < meta charset = utf8 >我是 pyyuc 站点
  • Nginx访问日志功能

    日志功能对每个用户访问网站的日志信息记录到指定的日志文件里,开发运维人员可以分析用户的浏览器行为,此功能由ngx_http_log_module模块负责,官网地址是:

    http://nginx.org/en/docs/http/ngx_http_log_module.html

    控制日志的参数

  • log_format 记录日志的格式,可定义多种格式
  • accsss_log 指定日志文件的路径以及格式
  • log_format main ‘$remote_addr - $remote_user [$time_local] “$request” ‘
    ‘$status $body_bytes_sent “$http_referer” ‘
    ‘“$http_user_agent” “$http_x_forwarded_for”‘;

    对应参数解析

  • $remote_addr 记录客户端 ip
  • $remote_user 远程用户,没有就是 “-”
  • $time_local 对应[ 14 / Aug / 2018 : 18 : 46 : 52 + 0800 ]
  • $request 对应请求信息 "GET /favicon.ico HTTP/1.1"
  • $status 状态码
  • $body_bytes_sent 571 字节 请求体的大小
  • $http_referer 对应“-”  由于是直接输入浏览器就是 -
  • $http_user_agent 客户端身份信息
  • $http_x_forwarded_for 记录客户端的来源真实 ip 97.64 . 34.118
  • 日志效果如下

  • 66.102 . 6.6 - - [ 14 / Aug / 2018 : 18 : 46 : 52 + 0800 ] "GET /favicon.ico HTTP/1.1" 404 571 "-"
  • "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.75 Safari/537.36 Google Favicon" "97.64.34.118"
  • nginx.conf默认配置

  • log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  • '$status $body_bytes_sent "$http_referer" '
  • '"$http_user_agent" "$http_x_forwarded_for"' ;
  • access_log logs / access . log main ;
  • 日志格式配置定义

  • log_format 是日志关键字参数,不能变
  • main 是日志格式指定的标签,记录日志时通过 main 标签选择指定的格式。
  • Nginx404页面优化

    在网站运行过程中,可能因为页面不存在等原因,导致网站无法正常响应请求,此时web服务会返回系统的错误码,但是默认的错误页面很不友好。

  • include mime . types ;
  • default_type application / octet - stream ;
  • log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  • '$status $body_bytes_sent "$http_referer" '
  • '"$http_user_agent" "$http_x_forwarded_for"' ;
  • access_log logs / access . log main ;
  • sendfile on ;
  • keepalive_timeout 65 ;
  • server {
  • listen 80 ;
  • server_name 192.168 . 11.63 ;
  • location / {
  • proxy_pass http : //192.168.11.64;
  • root html ;
  • index index . html index . htm ;
  • error_page 500 502 503 504 / 50x . html ;
  • location = / 50x . html {
  • root html ;
  • 此时访问master的服务器192.168.11.63:80地址,已经会将请求转发给slave的80端口

    除了页面效果的展示以外,还可以通过log(access.log)查看代理效果

    63端日志

    64端日志

    9.1 nginx负载均衡

  • Web 服务器,直接面向用户,往往要承载大量并发请求,单台服务器难以负荷,我使用多台 WEB 服务器组成集群,前端使用 Nginx 负载均衡,将请求分散的打到我们的后端服务器集群中,
  • 实现负载的分发。那么会大大提升系统的吞吐率、请求性能、高容灾
  • Nginx代理仅代理一台服务器,而Nginx负载均衡则是将客户端请求代理转发至一组upstream虚拟服务池

    Nginx可以配置代理多台服务器,当一台服务器宕机之后,仍能保持系统可用。

    upstream配置

    在nginx.conf > http 区域中

  • upstream django {
  • server 10.0 . 0.10 : 8000 ;
  • server 10.0 . 0.11 : 9000 ;
  • 在nginx.conf > http 区域 > server区域 > location配置中

    添加proxy_pass

  • location / {
  • root html ;
  • index index . html index . htm ;
  • proxy_pass http : //django;
  • 此时初步负载均衡已经完成,upstream默认按照轮训方式负载,每个请求按时间顺序逐一分配到后端节点。

    upstream分配策略

  • 调度算法 概述
  • 轮询 按时间顺序逐一分配到不同的后端服务器(默认)
  • weight 加权轮询, weight 值越大,分配到的访问几率越高
  • ip_hash 每个请求按访问 IP hash 结果分配,这样来自同一 IP 的固定访问一个后端服务器
  • url_hash 按照访问 URL hash 结果来分配请求,是每个 URL 定向到同一个后端服务器
  • least_conn 最少链接数,那个机器链接数少就分发
  • 1.轮询(不做配置,默认轮询)

    2.weight权重(优先级)

    3.ip_hash配置,根据客户端ip哈希分配,不能和weight一起用weight 权重

  • upstream django {
  • server 10.0 . 0.10 : 8000 weight = 5 ;
  • server 10.0 . 0.11 : 9000 weight = 10 ;#这个节点访问比率是大于 8000
  • ip_hash

  • 每个请求按访问 ip hash 结果分配,这样每个访客固定访问一个后端服务器
  • upstream django {
  • ip_hash ;
  • server 10.0 . 0.10 : 8000 ;
  • server 10.0 . 0.11 : 9000 ;
  • backup

    在非backup机器繁忙或者宕机时,请求backup机器,因此机器默认压力最小

  • upstream django {
  • server 10.0 . 0.10 : 8000 weight = 5 ;
  • server 10.0 . 0.11 : 9000 ;
  • server node . oldboy . com : 8080 backup ;
  • Nginx实验负载均衡

  • 角色 ip 主机名
  • lb01 192.168 . 119.10 lb01
  • web01 192.168 . 119.11 web01
  • web02 192.168 . 119.12 web02
  • 关闭防火墙

  • iptables - F
  • sed - i 's/enforcing/disabled/' / etc / selinux / config
  • systemctl stop firewalld
  • systemctl disable firewalld
  • 一、web01服务器配置nginx,创建index.html

  • server {
  • listen 80 ;
  • server_name 192.168 . 119.11 ;
  • location / {
  • root / node ;
  • index index . html index . htm ;
  • mkdir / node
  • echo 'i am web01' > /node/ index . html
  • #启动NGINX
  • ./ sbgin / nginx
  • 二、web01服务器配置nginx,创建index.html

  • server {
  • listen 80 ;
  • server_name 192.168 . 119.12 ;
  • location / {
  • root / node ;
  • index index . html index . htm ;
  • mkdir / node
  • echo 'i am web02...' > /node/ index . html
  • #启动nginx
  • ./ sbing / nginx
  • 三、配置lb01服务器的nginx负载均衡

    1.检查lb01的 nginx.conf

  • http {
  • include mime . types ;
  • default_type application / octet - stream ;
  • sendfile on ;
  • keepalive_timeout 65 ;
  • upstream node {
  • server 192.168 . 119.11 : 80 ;
  • server 192.168 . 119.12 : 80 ;
  • server {
  • listen 80 ;
  • server_name 192.168 . 119.10 ;
  • location / {
  • proxy_pass http : //node;
  • include proxy_params ; #需要手动创建
  • 2.手动创建proxy_params文件,文件中存放代理的请求头相关参数

  • [ root@lb01 conf ]# cat / opt / nginx / conf / proxy_params
  • proxy_set_header Host $http_host ;
  • proxy_set_header X - Real - IP $remote_addr ;
  • proxy_set_header X - Forwarded - For $proxy_add_x_forwarded_for ;
  • proxy_connect_timeout 30 ;
  • proxy_send_timeout 60 ;
  • proxy_read_timeout 60 ;
  • proxy_buffering on ;
  • proxy_buffer_size 32k ;
  • proxy_buffers 4 128k ;
  • 系统 服务 软件 ip 地址
  • centos7 ( lb01 ) 负载均衡 nginx proxy 192.168 . 119.10
  • centos7 ( web01 ) 静态资源 nginx 静态资源 192.168 . 119.11
  • centos7 ( web02 ) 动态资源 django 192.168 . 119.12
  • 一、在web01机器上,配置静态资源,图片等

  • cat nginx . conf
  • server {
  • listen 80 ;
  • server_name 192.168 . 119.11 ;
  • #定义网页根目录
  • root / code ;
  • #定义了静态资源
  • index index . html ;
  • #域名匹配,所有的png、jpg、gif请求资源,都去/root/code/images底下找
  • location ~* .* \. ( png | jpg | gif ) $ {
  • root / code / images ;
  • #重启nginx
  • ./ sbin / nginx
  • static files ...
  • #准备静态文件,图片
  • [ root@web01 / code / images ] $wget http : //pythonav.cn/av/girlone.jpg^C
  • [ root@web01 / code / images ] $ls
  • girlone . jpg
  • 二、在web02配置动态请求,准备一个flask程序和静态资源转发

  • cat nginx . conf
  • #静态资源地址
  • upstream static {
  • server 192.168 . 119.11 : 80 ;
  • #flask动态请求
  • upstream flask {
  • server 192.168 . 119.12 : 8080 ;
  • server {
  • listen 80 ;
  • server_name 192.168 . 119.12 ;
  • #当请求到达192.168.119.12:80/时,转发给flask的8080应用
  • location / {
  • proxy_pass http : //flask;
  • include proxy_params ;
  • #当判断资源请求是 192.168.119.12/girl.jpg时候,转发请求给static地址池的服务器192.168.119.11/
  • location ~ .* \. ( png | jpg | gif ) $ {
  • proxy_pass http : //static;
  • include proxy_params ;
  • 准备flask应用,flask.py

  • from flask import Flask
  • app = Flask ( __name__ )
  • @app . route ( '/' )
  • def hello ():
  • return "i am flask....from nginx"
  • if __name__ == "__main__" :
  • app . run ( host = '0.0.0.0' , port = 8080 )
  • 后台运行flask程序

  • python flask - web . py &
  • 三、在负载均衡服务器lb01上测试访问192.168.119.10