赞
踩
远程链接工具说明:
MobaXterm.Xshell
关于服务部署的流程:
当新建虚拟机时,修改mac网络地址.
1.检查IP地址 ip addr
如果没有IP展现则执行如下的命令
service NetworkManager stop
chkconfig NetworkManager off 永久关闭 Manager网卡
service network restart 重启network网卡
2.进入ip修改目录 cd /etc/sysconfig/network-scripts/
3.修改IP地址 vim ifcfg-ens33 (进入ifcfg-ens33文件修改ip地址)
修改完成之后 保存退出即可.
4.在重启网卡service network restart(要重启网卡才能刷新ip地址)
5.在检查IP ip addr
1.上传JDK,拿到JDKLinux版本,放在创建的目录下,比如(/usr/local/src/)下
2.解压JDK,命令: tar -xvf jdk-8u51-linux-x64.tar.gz
3.修改文件名称,命令: mv (想要修改的文件名) (取名)
4.移动文件,将所有的.tar/.gz的包 保存到soft目录中
命令: mv (想要移动的文件) (放到指定的文件目录)
5.配置JDK环境变量
说明: 如果需要修改JDK的环境变量则需要修改特定的文件
位置: /etc/profile
注意事项: 由于profile的文件是系统文件, 千万改对了 否则整个Linux命令将不生效.
命令: vim /etc/profile
#设定jdk环境
export JAVA_HOME=/usr/local/src/jdk1.8
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib
让环境变量生效: source /etc/profile
1.在java程序代码进行打包,可以先clear 在install打包成.war文件,打完包放在自己创建的目录,或者公司指定的目录
2.上传到LINUX服务器指定的目录下
3.在指定目录下进行发布
#初级命令:
java -jar 8081.war & java -jar 8082.war &
4.关于项目关闭说明
关于端口号被占用的说明:
图中所示端口号被占用.先释放端口,之后重启.
5.检索服务 jps
检查任意的服务命令: ps -ef | grep 服务名称
检索java服务
命令: ps -ef | grep java
命令2: 只检索java服务 jps
说明: ps -ef 表示获取当前Linux系统中的所有的服务信息. “|” 将管道之前的查询的结果当做参数传递给后边的操作
6.关闭进程:
7.关于服务器后台启动说明
说明: 通过java -jar的命令启动服务器时,需要保证当前的终端必须处于运行状态.一旦终端关闭则当前终端所启动的服务也会随之关闭.
解决方案: 可以实现tomcat服务器 :开启Linux后台运行.
命令:
nohup java -jar 8081.war -> 8081.log &
8.关于日志说明
查看文件
命令1: (喵一眼 ) cat 文件名称
命令2: tail -20 文件名称 只展现最后20行日志
命令3: tail -f 文件名称 实时展现日志更新信息
ctrl + c 退出
9.关于利用脚本直接启动多个tomcat服务器.
1.编辑脚本
文件名称: xxxx.sh
创建文件命令: vim start.sh
启动脚本: sh start.sh
1.下载nginx服务
说明:利用Linux中提供的远程下载机制可以将nginx安装包直接下载到指定的位置.
命令: wget http://nginx.org/download/nginx-1.19.2.tar.gz
2. 解压Nginx服务
命令: tar -xvf nginx-1.19.2.tar.gz
2.1 将压缩文件移动到指定文件,统一管理
mv nginx-1.19.4.tar.gz software/
3.安装nginx服务
1).进入解压后的文件配置nginx环境
2).编译nginx
命令:make
3).安装nginx
命令:make install
4).检查nginx安装位置
whereis nginx
4.关于Nginx目录说明
源文件目录: /usr/local/src/nginx 只负责程序的编译
工作目录: /usr/local/nginx 负责程序的运行.
5.Nginx实现反向代理
进入 /usr/local/nginx/sbin中
1). 命令: ./nginx 启动nginx服务
./nginx -s reload
./nginx -s stop
2). 检查nginx是否启动成功
3). 配置nginx 实现反向代理
1.配置图片的反向代理 image.jt.com ~~~~ xxxxxxx
2.配置tomcat集群的反向代理 manage.jt.com ~~~~~8081/8082
配置成功之后重启nginx服务器.
# 配置图片服务器 image.jt.com server { listen 80; server_name image.jt.com; location / { root /usr/local/src/images; } } #配置tomcat服务器集群 upstream jt { server localhost:8081; server localhost:8082; } server { listen 80; server_name manage.jt.com; location / { proxy_pass http://jt; } }
4).修改hosts文件
修改windows的hosts文件
# 京淘配置
#IP 域名 IP和域名关系映射,中间使用空格分隔
#127.0.0.1 image.jt.com
#127.0.0.1 manage.jt.com
#实现 nginx的配置
192.168.126.129 image.jt.com
192.168.126.129 manage.jt.com
127.0.0.1 www.jt.com
#Bug 有时在使用该软件时可能会出现丢失字母的现象.
127.0.0.1 sso.jt.co
1.检查系统是否可以连接外网,比如ping www.baidu.com 按Ctrl+C退出
2.下载数据库 yum install mariadb-server
2.1清空已安装文件 如果下载失败之后执行:yum clean all
2.2确认下载
2.3 安装完成提示
3.启动数据库 systemctl start mariadb
4.进行数据库初始化 mysql_secure_installation
5.设置密码,后面一直YYYY
5.1测试数据库用户名和密码是否有效
6.查询user表中的host/root/password
6.1 将user表中的host=“localhost” 改为 “%”
7.刷新数据库 命令:flush privileges;
8.连接数据库(前提要把防火墙关闭)
1.检查防火墙状态
命令: firewall-cmd --state
说明:防火墙中有一个配置文件,表示当Linux系统启动时防火墙应该如何操作!!!
2.告诉Linux系统以后开机时防火墙关闭
命令: systemctl disable firewalld.service
3.告诉Linux系统以后开机时防火墙开启
命令:systemctl enable firewalld.service
4.手动关闭防火墙
systemctl stop firewalld.service
5. 手动启动防火墙:
systemctl start firewalld.service
6.手动开放防火墙端口
先检查防火墙的端口号 firewall-cmd --list-ports
检查80端口是否开放 firewall-cmd --query-port 80/tcp
7.开启防火墙端口可以使用80端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
(设置此端口号,防火墙开启状态,设置的端口号不会被防火墙拦截)
可以移除端口号 firewall-cmd --zone=public --remove-port=9090/tcp --permament
8.关于防火墙操作的解释
–zone #作用域
–add-port=80/tcp #添加端口,格式为:端口/通讯协议
–remove-port=80/tcp #移除端口,格式为:端口/通讯协议
–permanent #永久生效,没有此参数重启后失效
8.重启防火墙
firewall-cmd --reload
9.连接数据库(前提要把防火墙关闭)
yum -y install net-tools
缓存机制说明:
使用缓存可以有效的降低用户访问物理设备的频次.快速从内存中获取数据,之后返回给用户,同时需要保证内存中的数据就是数据库数据.
思考:
1.缓存的运行环境应该在内存中.(快)
2.使用C语言开发缓存
3.缓存应该使用什么样的数据结构呢--------K-V结构 一般采用String类型居多 key必须唯一 . v:JSON格式
4.内存环境断电即擦除,所以应该将内存数据持久化(执行写盘操作)
5.如果没有维护内存的大小,则容易导致 内存数据溢出. 采用LRU算法优化!!!
1.Redis安装
1)解压redis的安装包
把redis的压缩包放到 /usr/local/src目录下,
然后解压命令:tar -zxvf redis-5.0.4.tar.gz
2) 安装Redis
说明:在Redis的根目录中执行命令:
先进入根目录:cd /usr/local/src/redis
命令: 1.make
2.make install
2. 修改Redis的配置文件
先进入redis的配置文件: vim redis.conf
命令1: 展现行号 :set nu
修改位置1: 注释IP绑定(注释只允许本机使用)
修改位置2: 关闭保护模式(修改保护权限为no,允许别人访问)
修改位置3: 开启后台启动
3. redis 服务器命令
cd /usr/local/src/redis
进入redis根目录执行
1.启动命令: redis-server redis.conf
2.检索命令: ps -ef | grep redis
3.要操作redis就进入客户端: redis-cli -p 6379
4.关闭redis: kill -9 PID号 | redis-cli -p 6379 shutdown
4. Redis入门案例
4.1 引入jar包文件
<!--spring整合redis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
4.2编辑测试API
package com.jt.test; import org.junit.jupiter.api.Test; import redis.clients.jedis.Jedis; public class TestRedis { /** * 1.测试redis程序链接是否正常 * 步骤: * 1.实例化jedis工具API对象(host:port) * 2.根据实例 操作redis 方法就是命令 * * 关于链接不通的说明: * 1.检查Linux防火墙 * 2.检查Redis配置文件修改项 * 2.1 IP绑定 * 2.2 保护模式 * 2.3 后台启动 * 3.检查redis启动方式 redis-server redis.conf * 4.检查IP 端口 及redis是否启动... * * */ @Test public void test01(){ String host = "192.168.126.129"; int port = 6379; Jedis jedis = new Jedis(host,port); jedis.set("cgb2006","好好学习 天天向上"); System.out.println(jedis.get("cgb2006")); //2.练习是否存在key if(jedis.exists("cgb2006")){ jedis.del("cgb2006"); }else{ jedis.set("cgb2006", "xxxx"); jedis.expire("cgb2006", 100); } } }
1关于Redis持久化的说明
redis默认条件下支持数据的持久化操作. 当redis中有数据时会定期将数据保存到磁盘中.当Redis服务器重启时 会根据配置文件读取指定的持久化文件.实现内存数据的恢复.
2.持久化方式: RDB模式
特点:
1).RDB模式是redis的默认的持久化策略.
2).RDB模式记录的是Redis 内存数据的快照. 最新的快照会覆盖之前的内容 所有RDB持久化文件占用空间更小 持久化的效率更高.
3).RDB模式由于是定期持久化 所以可能导致数据的丢失.
命令:
4).配置:
进入redis.conf文件中,: vim redis.conf
1.持久化文件名称
2.持久化文件位置
dir ./ 相对路径的写法
dir /usr/local/src/redis 绝对路径写法
3.RDB模式持久化策略
3.持久化方式: AOF模式
特点:
1.AOF模式默认条件下是关闭的,需要用户手动的开启
2. AOF模式是异步的操作 记录的是用户的操作的过程 可以防止用户的数据丢失
3. 由于AOF模式记录的是程序的运行状态 所以持久化文件相对较大,恢复数据的时间长.需要人为的优化持久化文件
配置:
4.关于持久化操作的总结
1.如果不允许数据丢失 使用AOF方式
2.如果追求效率 运行少量数据丢失 采用RDB模式
3.如果既要保证效率 又要保证数据 ,一般在工作中采用RDB+AOF模式共同作用,保证数据的有效性,则应该配置redis的集群 主机使用RDB 从机使用AOF
1.需要redis的根目录找到 appendonly.aof文件 , 命令 : vim appendonly.aof
2.将flushall命令删除后保存
3.之后重启redis,执行save命令即可
关闭:redis-cli -p 6379 shutdown
启动:redis-server redis.conf
4.进入redis-cli -p 6379 然后执行save命令
说明:Redis数据的存储都在内存中.如果一直想内存中存储数据 必然会导致内存数据的溢出.
解决方式:
1.LRU算法
特点: 最好用的内存优化算法.
LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。
维度: 时间 T
2. LFU算法
LFU(least frequently used (LFU) page-replacement algorithm)。即最不经常使用页置换算法,要求在页置换时置换引用计数最小的页,因为经常使用的页应该有一个较大的引用次数。但是有些页在开始时使用次数很多,但以后就不再使用,这类页将会长时间留在内存中,因此可以将引用计数寄存器定时右移一位,形成指数衰减的平均使用次数。
维度: 使用次数
3.RANDOM算法
随机删除数据
4.TTL算法
把设定了超时时间的数据将要移除的提前删除的算法.
5. Redis内存数据优化
volatile-lru 设定了超时时间的数据采用lru算法
2.allkeys-lru 所有的数据采用LRU算法
3.volatile-lfu 设定了超时时间的数据采用lfu算法删除
4.allkeys-lfu 所有数据采用lfu算法删除
5.volatile-random 设定超时时间的数据采用随机算法
6.allkeys-random 所有数据的随机算法
7.volatile-ttl 设定超时时间的数据的TTL算法
8.noeviction 如果内存溢出了 则报错返回. 不做任何操作. 默认值
从redis根目录进入redis.conf进行设置: vim redis.conf
注意:一个Linux系统中只能安装一个mysql数据库,所以需要重新开一个虚拟机操作,新建虚拟机ip地址不能一样,需要修改ip
安装数据库,参考第一章中的数据库安装
1.为什么需要搭建Mysql集群
描述: 如果项目中使用单台数据库,如果由于不可抗因素导致设备损坏,数据丢失,将直接影响用户的使用.需要需要进行优化.
2.数据库热备份
说明: 由于数据库的同步的操作在工作中特别的频繁,所以作为数据库的开发人员,也设计了数据库如何进行同步.
同步的步骤:
3.实现数据库主从搭建
在192.168.126.129主库中
1). 开启主库二进制文件
切换到:cd /usr/local/src
修改主库配置
命令: vim /etc/my.cnf
插入: 服务器编号 server-id=1
二进制日志文件 log-bin=mysql-bin
2).重启数据库
说明:当修改完成配置文件之后,需要重启数据库,使得二进制文件生效.
跳入文件: cd /var/lib/mysql/
重启数据库: systemctl restart mariadb
在192.168.126.130中
3).配置从数据库
说明:根据主数据库的配置信息 配置从数据库 如图所示 配置完成之后,重启数据库即可
4.实现主从的挂载
主库: 192.168.126.129 master
从库: 192.168.126.130 slave
在SQLyog中,在192.168.126.129 数据库中
4.1)检查主库状态信息
声明:(mysql-bin.000001 只要重启数据库则二进制日志文件+1)(mysql-bin.index 二进制日志文件)
在SQLyog中,在192.168.126.130 数据库中
4.2)实现主从挂载
1.确定主库中二进制日志文件信息
执行sql命令: show master status; /*我是130 我是从库 默认条件下数据库都是主库 host/port/user/password/二进制文件/pos */ CHANGE MASTER TO MASTER_HOST="192.168.126.130", MASTER_PORT=3306, MASTER_USER="root", MASTER_PASSWORD="root", MASTER_LOG_FILE="mysql-bin.000001", MASTER_LOG_POS=245; /*启动主从服务*/ START SLAVE; /*检查主从状态*/ SHOW SLAVE STATUS; /*1.关闭主从服务*/ STOP SLAVE;
1.说明
说明:由于需要用户同时链接2台甚至多台数据库时需要引入代理,来实现读写分离,负载均衡,所以有如下的部署.
注意事项: 用户链接代理服务器 端口号一般:8066端口
2.Mycat介绍
3.Mycat部署
3.1上传Mycat安装包
3.2解压Mycat压缩包:
命令: tar -xvf Mycat-server-1.7.0-DEV-20170416134921-linux.tar.gz
3.3 检查JDK是否安装
进入: cd /usr/locsl/src/mycat/conf
4.关于Mycat配置文件说明
4.1server.xml配置文件说明
说明:在server.xml配置文件中定义用户名和密码及操作的数据库信息,必须与YML配置文件一致.
4.2.修改YML配置文件
4.3 schemas配置文件说明
说明:schemas文件主要的作用就是配置数据库读写的策略.
<writeHost host="hostM1" url="192.168.126.129:3306" user="root" password="root">
<!--读数据库1-->
<readHost host="hostS1" url="192.168.126.130:3306" user="root" password="root" />
<!--读数据库2-->
<readHost host="hostS2" url="192.168.126.129:3306" user="root" password="root" />
</writeHost>
5. Mycat测试
进入bin目录:cd /usr/local/src/mycat/bin
启动命令: ./mycat start
Mycat测试:
6.数据库实现高可用
高可用: 保证服务尽可能的不宕机,保证用户正常使用.
6.1 数据库双机热备
说明:一般在公司中配置双机热备的形式,配置为互为主从.
配置说明:
1.主库 192.168.126.130
2.从库 192.168.126.129
/*实现主从的挂载*/
CHANGE MASTER TO MASTER_HOST="192.168.126.130",
MASTER_PORT=3306,
MASTER_USER="root",
MASTER_PASSWORD="root",
MASTER_LOG_FILE="mysql-bin.000001",
MASTER_LOG_POS=482
/*启动主从服务*/
START SLAVE
/*检查主从状态*/
SHOW SLAVE STATUS;
6.2实现数据库高可用配置
说明:修改完成数据库之后,将配置文件上传即可.
<?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <!--name属性是自定义的 dataNode表示数据库的节点信息 jtdb表示逻辑库--> <schema name="jtdb" checkSQLschema="false" sqlMaxLimit="100" dataNode="jtdb"/> <!--定义节点名称/节点主机/数据名称--> <dataNode name="jtdb" dataHost="localhost1" database="jtdb" /> <!--参数介绍 UTF-8 中文报错--> <!--balance 0表示所有的读操作都会发往writeHost主机 --> <!--1表示所有的读操作发往readHost和闲置的主节点中--> <!--writeType=0 所有的写操作都发往第一个writeHost主机--> <!--writeType=1 所有的写操作随机发往writeHost中--> <!--dbType 表示数据库类型 mysql/oracle--> <!--dbDriver="native" 固定参数 不变--> <!--switchType=-1 表示不自动切换, 主机宕机后不会自动切换从节点--> <!--switchType=1 表示会自动切换(默认值)如果第一个主节点宕机后,Mycat会进行3次心跳检测,如果3次都没有响应,则会自动切换到第二个主节点--> <!--并且会更新/conf/dnindex.properties文件的主节点信息 localhost1=0 表示第一个节点.该文件不要随意修改否则会出现大问题--> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <!--心跳检测--> <heartbeat>select 1</heartbeat> <!--配置第一台主机主要进行写库操作,在默认的条件下Mycat主要操作第一台主机在第一台主机中已经实现了读写分离.因为默认写操作会发往137的数据库.读的操作默认发往141.如果从节点比较忙,则主节点分担部分压力. --> <writeHost host="hostM1" url="192.168.126.129:3306" user="root" password="root"> <!--读数据库1--> <readHost host="hostS1" url="192.168.126.130:3306" user="root" password="root" /> <!--读数据库2--> <readHost host="hostS2" url="192.168.126.129:3306" user="root" password="root" /> </writeHost> <!--定义第二台主机 由于数据库内部已经实现了双机热备.--> <!--Mycat实现高可用.当第一个主机137宕机后.mycat会自动发出心跳检测.检测3次.--> <!--如果主机137没有给Mycat响应则判断主机死亡.则回启东第二台主机继续为用户提供服务.--> <!--如果137主机恢复之后则处于等待状态.如果141宕机则137再次持续为用户提供服务.--> <!--前提:实现双机热备.--> <writeHost host="hostM2" url="192.168.126.130:3306" user="root" password="root"> <readHost host="hostS1" url="192.168.126.130:3306" user="root" password="root" /> <readHost host="hostS2" url="192.168.126.129:3306" user="root" password="root" /> </writeHost> </dataHost> </mycat:schema>
6.3 实现数据库高可用测试
测试步骤:
1.关闭主数据库,之后检索数据,检查用户的访问是否受限:
关闭129.168.126.129数据库:systemctl stop mariadb
2.修改数据库记录,检查用户的操作是否正常. (操作的是从库):
然后新增一个数据,看是否存入129.168.126.130库
3.重启主数据库 之后检查从库的数据是否同步.
redis分片就是为了实现内存数据的扩容.
如果需要存储海量的内存数据,如果只使用一台redis,无法保证redis工作的效率. 大量的时间都浪费到了寻址当中.所以需要一种机制能够满足该要求.
采用分片机制实现:
如果有多台redis,则每台存储的数据都不一样
1.Redis分片搭建
1)Redis服务的启动需要依赖于redis.conf的配置文件. 如果需要准备3台redis.则需要准备3个redis.conf的配置.
准备端口号:
1.6379
2.6380
3.6381
进入redis根目录: cd /usr/local/src/redis
创建目录: mkdir shards
复制3份redis.conf文件到shards目录:
cp redis.conf shards/6379.conf
2.修改端口号: 将各自的端口号进行修改.
进入shards目录开始编辑
命令: vim 6379.conf
3.启动3台redis服务器
校验服务器是否正常运行
4.分片测试案例
1.问题描述:
当启动多台redis服务器之后,多台redis暂时没有必然的联系,各自都是独立的实体.可以数据数据的存储.如图所示.
2.如果将分片通过程序的方式进行操作,要把3台redis当做一个整体,所以与上述的操作完全不同.不会出现一个key同时保存到多个redis的现象.
/** * 测试Redis分片机制 * 思考: shards 如何确定应该存储到哪台redis中呢??? */ @Test public void testShards(){ List<JedisShardInfo> shards = new ArrayList<>(); shards.add(new JedisShardInfo("192.168.126.129",6379)); shards.add(new JedisShardInfo("192.168.126.129",6380)); shards.add(new JedisShardInfo("192.168.126.129",6381)); //准备分片对象 ShardedJedis shardedJedis = new ShardedJedis(shards); shardedJedis.set("shards","redis分片测试"); System.out.println(shardedJedis.get("shards")); }
5.一致性hash算法
1)常识说明
常识1: 一般的hash是8位16进制数. 0-9 A-F (24)8 = 2^32
常识2: 如果对相同的数据进行hash运算 结果必然相同的.
常识3: 一个数据1M 与数据1G的hash运算的速度一致.
2)一致性hash算法介绍
一致性哈希算法在1997年由麻省理工学院提出,是一种特殊的哈希算法,目的是解决分布式缓存的问题。 [1] 在移除或者添加一个服务器时,能够尽可能小地改变已存在的服务请求与处理请求服务器之间的映射关系。一致性哈希解决了简单哈希算法在分布式哈希表( Distributed Hash Table,DHT) 中存在的动态伸缩等问题 [2] 。
3)特性1-平衡性
概念:平衡性是指hash的结果应该平均分配到各个节点,这样从算法上解决了负载均衡问题 [4] 。(大致平均)
问题描述: 由于节点都是通过hash方式进行算计.所以可能出现如图中的现象.,导致负载严重不平衡
解决方法: 引入虚拟节点
4) 特性2-单调性
特点: 单调性是指在新增或者删减节点时,不影响系统正常运行 [4] 。
5) 特性3-分散性
谚语: 鸡蛋不要放到一个篮子里.
③分散性是指数据应该分散地存放在分布式集群中的各个节点(节点自己可以有备份),不必每个节点都存储所有的数据 [4]
6.SpringBoot整合Redis分片
1)编辑配置文件
# 配置redis单台服务器
redis.host=192.168.126.129
redis.port=6379
# 配置redis分片机制
redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381
2)编辑配置类
@Configuration @PropertySource("classpath:/properties/redis.properties") public class JedisConfig { @Value("${redis.nodes}") private String nodes; //node,node,node..... //配置redis分片机制 @Bean public ShardedJedis shardedJedis(){ nodes = nodes.trim(); //去除两边多余的空格 List<JedisShardInfo> shards = new ArrayList<>(); String[] nodeArray = nodes.split(","); for (String strNode : nodeArray){ //strNode = host:port String host = strNode.split(":")[0]; int port = Integer.parseInt(strNode.split(":")[1]); JedisShardInfo info = new JedisShardInfo(host, port); shards.add(info); } return new ShardedJedis(shards); } }
3)修改AOP注入项
1.关于Redis分片说明
优点: 实现内存数据的扩容.
缺点: 如果redis分片中有一个节点出现了问题.,则整个redis分片机制用户访问必然有问题 直接影响用户的使用.
解决方案: 实现redis高可用.
配置redis主从的结构
2.配置redis主从的结构
策略划分: 1主2从 6379主 6380/6381从
1.将分片的目录复制 改名位sentinel
命令:cp -r shards sentinel
2.进入: cd sentinel ,只留着三个conf文件,其余的删除
重启三台redis服务器: redis-server 6379.conf
检测redis是否开启: ps -ef |grep redis
3.检查redis节点的主从的状态 (其实每台redis都是主机)
进入其中端口号为6379的redis: redis-cli -p 6379
检测主从状态: info replication
4.实现主从挂载
进入6380: redis-cli -p 6380
将6380设置为6379的从机
命令: slaveof 192.168.126.129 6379
检测是否挂在成功: info replication
将6381也设置为6379的从机
5.检查主机的状态
3.哨兵的工作原理
原理说明:
1.配置redis主从的结构.
2.哨兵服务启动时,会监控当前的主机. 同时获取主机的详情信息(主从的结构)
3.当哨兵利用心跳检测机制(PING-PONG) 连续3次都没有收到主机的反馈信息则断定主机宕机.
4.当哨兵发现主机宕机之后,则开启选举机制,在当前的从机中挑选一台Redis当做主机.
5.将其他的redis节点设置为新主机的从.
4.编辑哨兵配置文件
1).将sentinel.conf文件复制到sentinel目录下
命令:cp sentinel.conf sentinel/
2).修改保护模式
进入sentinel目录编辑sentinel.conf文件 命令: vim sentinel.conf
关闭保护模式
3).开启后台运行
4).设定哨兵的监控
其中的1 表示投票生效的票数 当前只有一个哨兵所以写1
5).修改主机宕机后多少毫秒后重新选举
6).选举失败的时间
说明:如果选举超过指定的时间没有结束,则重新选举.避免死锁
保存
7).启动哨兵服务
命令:redis-sentinel sentinel.conf
检索是否启动:ps -ef |grep redis
5.测试步骤:
1.检查主机的状态
2.将redis主服务器宕机 等待10秒 之后检查从机是否当选新的主机
3.重启6379服务器., 检查是否成为了新主机的从.
1. 为什么需要搭建集群
redis分片特点:
1.可以实现Redis内存数据的扩容.
2.redis分片本身没有高可用效果的.如果宕机将直接影响用户的使用.
redis哨兵特点:
1.Redis哨兵可以实现Redis节点的高可用.但是哨兵本身没有实现高可用机制.(最好不要引入第三方)
2.Redis哨兵有主从的结构 实现了内存数据的备份. 但是没有实现内存扩容的效果.
升级:
为了提高网站响应速度,总是把热点数据保存在内存中而不是直接从后端数据库中读取。
需要Redis内容扩容同时需要Redis高可用性所以应该使用Redis集群.
2.准备集群文件夹
1)在redis的根目录 cd /usr/local/src 创建集群文件夹:Mkdir cluster
2)在cluster文件夹中分别创建7000-7005文件夹
3.编辑配置文件
1)复制配置文件
将redis根目录中的redis.conf文件复制到cluster/7000/ 并以原名保存
cp redis.conf cluster/7000/
2)编辑配置文件
2.1 注释本地绑定IP地址
2.2.关闭保护模式
2.3.修改端口号
2.4.启动后台启动
2.5.修改pid文件
/usr/local/src/redis/cluster/7000/redis.pid
2.6.修改持久化文件路径
/usr/local/src/redis/cluster/7000
2.7.设定内存优化策略
2.8.关闭AOF模式,改成RDB模式
2.9.开启集群配置
2.10.开启集群配置文件,分目录存储
2.11改集群超时时间
4.复制修改后的配置文件
1).说明:将7000文件夹下的redis.conf文件分别复制到7001-7005中
cp 7000/redis.conf 7001/
[root@localhost cluster]# cp 7000/redis.conf 7001/
[root@localhost cluster]# cp 7000/redis.conf 7002/
[root@localhost cluster]# cp 7000/redis.conf 7003/
[root@localhost cluster]# cp 7000/redis.conf 7004/
[root@localhost cluster]# cp 7000/redis.conf 7005/
2).批量修改
说明:分别将7001-7005文件中的7000改为对应的端口号的名称,
修改时注意方向键的使用
2.1先进入7001目录: cd 7001
2.2编辑redis.conf文件:vim redis.conf
2.3将7000端口批量改成7001命令:%s/7000/7001/g
2.4分别进入其他的目录(7002,7003,7004,7005)进行上述操作
5.通过脚本编辑启动/关闭指令
在集群目录下: cd /usr/local/src/redis/cluster
1.创建启动脚本 vim start.sh
2.编辑关闭的脚本 vim shutdown.sh
3.启动redis节点
命令:sh start.sh
4.检查redis节点启动是否正常
命令:ps -ef |grep redis
5.如果报错,先查防火墙是否开启:firewall-cmd --state
6.关闭防火墙:systemctl stop firewalld.service
6.创建redis集群
在 cluster 目录下,执行下面命令(下面命令中的1为一个主机后面搭1台从机):
#5.0版本执行 使用C语言内部管理集群
redis-cli --cluster create --cluster-replicas 1 192.168.126.129:7000 192.168.126.129:7001 192.168.126.129:7002 192.168.126.129:7003 192.168.126.129:7004 192.168.126.129:7005
7.Redis集群高可用测试
1.关闭redis主机.检查是否自动实现故障迁移.
2.再次启动关闭的主机.检查是否能够实现自动的挂载.
一般情况下 能够实现主从挂载
个别情况: 宕机后的节点重启,可能挂载到其他主节点中(7001-7002) 正确的
8.Redis集群原理
1)Redis集群高可用推选原理
Redis的所有节点都会保存当前redis集群中的全部主从状态信息.并且每个节点都能够相互通信.当一个节点发生宕机现象.则集群中的其他节点通过PING-PONG检测机制检查Redis节点是否宕机.当有半数以上的节点认为宕机.则认为主节点宕机.同时由Redis剩余的主节点进入选举机制.投票选举链接宕机的主节点的从机.实现故障迁移.
2)Redis集群宕机条件
特点:集群中如果主机宕机,那么从机可以继续提供服务,
当主机中没有从机时,则向其它主机借用多余的从机.继续提供服务.如果主机宕机时没有从机可用,则集群崩溃.
答案:9个redis节点,节点宕机5-7次时集群才崩溃.
如图-25所示:
3)redis集群数据存储原理:
在redis cluster中,如果想要存入一个key-value,
这个key首先会通过CRC16算法(和16384取余),
结果会对应上0-16383之间的哈希槽(hash slot)
最后,redis cluster会将key-value放置在对应的哈希槽中。
算法:哈希函数: Hash()=CRC16[key]%16384
4)redis集群数据获取原理:
当client向redis cluster中的任意一个节点发送与数据库key有关的命令时,
接收命令的节点会计算出要处理的key属于哪个哈希槽(hash slot),
并且先检查这个hash slot是否属于自己(管辖):
如果key所在的槽正好属于自己(管辖),节点会直接执行这个key相关命令。
如果key所在的槽不属于自己(管辖),那么节点会给client返回一个MOVED错误,
指引client转向负责对应槽的节点,并客户端需要再次发送想要执行的和key相关的命令。
1.编辑pro配置文件
# 配置redis单台服务器
redis.host=192.168.126.129
redis.port=6379
# 配置redis分片机制
redis.nodes=192.168.126.129:6379,192.168.126.129:6380,192.168.126.129:6381
# 配置哨兵节点
redis.sentinel=192.168.126.129:26379
# 配置redis集群
redis.clusters=192.168.126.129:7000,192.168.126.129:7001,192.168.126.129:7002,192.168.126.129:7003,192.168.126.129:7004,192.168.126.129:7005
2.编辑RedisConfig配置类
@Configuration @PropertySource("classpath:/properties/redis.properties") public class RedisConfig { //配置redis集群 @Value("${redis.clusters}") private String clusters; @Bean public JedisCluster jedisCluster(){ clusters = clusters.trim(); //去除两边空格 HashSet<HostAndPort> nodeSet = new HashSet<>(); String[] nodes= clusters.split(","); //按逗号切割成192.168.126.129:7000 for (String node:nodes) { String host=node.split(":")[0]; //按冒号切割成 host=192.168.126.129 int port=Integer.parseInt(node.split(":")[1]); HostAndPort hostAndPort = new HostAndPort(host,port); nodeSet.add(hostAndPort); } return new JedisCluster(nodeSet); }
3.编辑ObjectMapper工具API
package com.jt.util; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; public class ObjectMapperUtil { private static final ObjectMapper MAPPER = new ObjectMapper(); //将对象转化为JSON public static String toJSON(Object target){ try { return MAPPER.writeValueAsString(target); } catch (JsonProcessingException e) { e.printStackTrace(); throw new RuntimeException(e); } } //将JSON转化为对象 //需求: 如果用户传递什么类型,则返回什么对象 public static <T> T toObject(String json,Class<T> targetClass){ try { return MAPPER.readValue(json, targetClass); } catch (JsonProcessingException e) { e.printStackTrace(); throw new RuntimeException(e); } } }
4.编辑CacheAOP,将数据存入redis缓存
编辑自定义注解
@Target(ElementType.METHOD) //注解对方法有效
@Retention(RetentionPolicy.RUNTIME) //运行期有效
public @interface CacheFind {
public String preKey(); //定义key的前缀
public int seconds() default 0; //定义数据的超时时间.
}
编辑CacheAOP
package com.jt.aop; import com.jt.anno.CacheFind; import com.jt.util.ObjectMapperUtil; import lombok.extern.apachecommons.CommonsLog; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.stereotype.Service; import redis.clients.jedis.Jedis; import java.lang.reflect.Method; import java.util.Arrays; @Aspect //标识我是一个切面 @Component //交给Spring容器管理 public class CacheAOP { @Autowired private JedisCluster jedis; /** * 注意事项: 当有多个参数时,joinPoint必须位于第一位. * 需求: * 1.准备key= 注解的前缀 + 用户的参数 * 2.从redis中获取数据 * 有: 从缓存中获取数据之后,直接返回值 * 没有: 查询数据库之后再次保存到缓存中即可. * * 方法: * 动态获取注解的类型,看上去是注解的名称,但是实质是注解的类型. 只要切入点表达式满足条件 * 则会传递注解对象类型. * @param joinPoint * @return * @throws Throwable */ @Around("@annotation(cacheFind)") public Object around(ProceedingJoinPoint joinPoint,CacheFind cacheFind) throws Throwable { Object result = null; //定义返回值对象 String preKey = cacheFind.preKey(); String key = preKey + "::" + Arrays.toString(joinPoint.getArgs()); //1.校验redis中是否有数据 if(jedis.exists(key)){ //如果数据存在,需要从redis中获取json数据,之后直接返回 String json = jedis.get(key); //1.获取方法对象, 2.获取方法的返回值类型 MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature(); //2.获取返回值类型 Class returnType = methodSignature.getReturnType(); result = ObjectMapperUtil.toObject(json,returnType); System.out.println("AOP查询redis缓存!!!"); }else{ //代表没有数据,需要查询数据库 result = joinPoint.proceed(); //将数据转化为JSON String json = ObjectMapperUtil.toJSON(result); if(cacheFind.seconds() > 0){ jedis.setex(key, cacheFind.seconds(), json); }else{ jedis.set(key,json); } System.out.println("AOP查询数据库!!!"); } return result; } }
1.Zookeeper介绍
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
总结:Zookeeper负责服务的协调调度.当客户端发起请求时,返回正确的服务器地址.
2.Zookeeper下载
官网: http://zookeeper.apache.org/releases.html
下载路径,点击download.
下载地址:http://mirrors.hust.edu.cn/apache/zookeeper/
3.Zookeeper安装
3.1)在cd /usr/local/src目录中,上传zookeeper安装文件.之后解压.
解压命令:tar -xvf zookeeper-3.4.8.tar.gz
3.2)改名
将apache-zookeeper-3.6.0-bin 命令:
mv apache-zookeeper-3.6.0-bin zookeeper
将mv apache-zookeeper-3.6.0-bin.tar.gz 移动到software 命令:
mv apache-zookeeper-3.6.0-bin.tar.gz software/
3.3)在zookeeper根目录创建文件夹data/log
命令: cd zookeeper/
创建文件夹:mkdir data log
3.4)跳入conf目录中修改配置文件
命令:cd conf
复制配置文件zoo_sample.cfg并且修改名称
命令:cp zoo_sample.cfg zoo.cfg
编辑zoo.cfg文件并保存:
命令:vim zoo.cfg
3.5)启动zookeeper
进入bin目录:cd bin/
启动: sh zkServer.sh start 或者 ./zkServer.sh start
关闭: sh zkServer.sh stop
查看状态: sh zkServer.sh status
4.Zookeeper集群安装
1.)先在bin目录查看zookeeper是否开启,需要关闭
查看:sh zkServer.sh status
关闭:sh zkServer.sh stop
2.)准备文件夹
在zookeeper根目录中创建新的文件夹zkCluster
进入:cd /usr/local/src/zookeeper
创建:mkdir zkClusters
3.)在zkClusters目录创建zk1/zk2/zk3文件夹.
命令:mkdir zk1 zk2 zk3
在zk1,zk2,zk3里分别创建data/log文件夹
命令:mkdir {zk1,zk2,zk3}/{data,log}
4)添加myid文件
分别在zk1/zk2/zk3中的data文件夹中创建新的文件myid.其中的内容依次为1/2/3,与zk节点号对应.
进入:cd zk1/data
编辑:vim myid
编辑myid文件,定义编号.
瞄一眼,看是否编辑正确
cat myid
5)编辑配置文件
5.1在conf文件夹中:
cd /usr/local/src/zookeeper/conf
5.2将zoo_sample.cfg 复制为zoo1.cfg之后修改配置文件
命令:cp zoo_sample.cfg zoo1.cfg
5.3修改zoo1.cfg
命令: vim zoo1.cfg
进行修改如图:
5.4配置完成后将zoo1.cfg复制2份.之后需要修改对应的文件夹目录.和不同的端口即可.
6)集群测试
进入bin目录:
cd /usr/local/src/zookeeper/bin
将集群启动
sh zkServer.sh start zoo1.cfg
sh zkServer.sh start zoo2.cfg
sh zkServer.sh start zoo3.cfg
查看主从关系:
sh zkServer.sh status zoo1.cfg
sh zkServer.sh status zoo2.cfg
sh zkServer.sh status zoo3.cfg
7)关于zookeeper集群说明
Zookeeper集群中leader负责监控集群状态,follower主要负责客户端链接获取服务列表信息.同时参与投票.
5.为什么集群是奇数台?
原则: 搭建集群必须满足公式 现有的节点数量 > N/2
为什么集群的最小单位是3台:
假设: 1台 1-1=0 > 1/2 假的
2台 2-1=1 > 2/2 假的
3台 3-1=2 > 3/2 真的 3台是搭建集群的最小单位.
4台 4-1=3 > 4/2 真的 只要大约3台都可以搭建集群.
从实用性的角度考虑问题 发现搭建奇数台和偶数台的容灾能力相同.所以选用奇数台.
6.zk集群选举的原理
原理说明: zk集群的选举根据最大值(myid)优先的规则,进行选举. 如果集群一旦超过半数以上的票数同意,则当选主机,同时选举结束.
问题: 有1,2,3,4,5,6,7节点依次启动.
问题1: 谁当主机? 4当主机
问题2: 哪几台永远不能当选主机? 1 2 3
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。