0%

1、准备工作

2、安装

  • 解压zookeeper到指定目录
1
2
3
4
# 解压
tar xf apache-zookeeper-3.6.3-bin.tar.gz
cd apache-zookeeper-3.6.3-bin/conf
cp zoo-example.cfg zoo.cfg
  • 配置文件配置
1
2
3
4
5
6
7
8
9
10
cd apache-zookeeper-3.6.3-bin/conf
vi zoo.cfg
# 数据文件路径:改路径下存放数据及myid文件
dataDir=/var/zookeeper/data
# zookeeper集群 server.1中的1对应myid文件中的id
server.1=zk-node01:2888:3888
server.2=zk-node02:2888:3888
server.3=zk-node03:2888:3888
# 只用来查询,没有leader选举的权力
server.4=zk-node04:2888:3888:observer
  • myid
1
echo 1 > /var/zookeeper/data/myid

3、启动

启动前可以先配置下环境变量,把zk可执行文件路径添加到PATH中

1
2
3
4
5
6
# 环境变量配置 vi /etc/profile
ZOOKEEPER_HOME=/opt/apache-zookeeper-3.6.3-bin
PATH=$PATH:$ZOOKEEPER_HOME/bin
export PATH ZOOKEEPER_HOME
# 启动:
zkServer.sh start

4、常用命令

1
2
3
4
5
6
# 前台启动,crtl+c后关闭
zkServer.sh start-foreground
# 查看状态
zkServer.sh status
# 客户端连接到zkServer
zkCli.sh

5、应用

简单列举几个命令,zk客户端的应用主要还是通过api来调用,即在client端写代码去操作zk。

5.1、create创建节点

create [-s] [-e] [-c] [-t ttl] path [data] [acl]

  • s:创建sequence节点。
  • e(ephemeral):创建临时节点。
  • path:节点路径。
  • data:数据。
1
create /xxx ""

image-20210724170408005

5.2、set设置数据

set [-s] [-v version] path data

1
set xxx "123"
5.3、get获取数据

get [-s] [-w] path

1
get /xxx
5.4、delete删除节点

delete [-v version] path

1
delete xxx

异或百度百科。异或操作相同为0,不同为1,时间长了很容易就忘记,辛得高人指点,有了另外一种记忆方式:异或即为相同位相加无进位。如1^1,舍弃进位即为0;1^0即为1。

1、运算法则

  • a^a=0。
  • a^0=a。
  • a^b=b^a。
  • a^b^c=(a^b)^c=(a^c)^b=a^(b^c)。
  • a^b^a=b。

根据上面的这些运算法则,可以运用到下面的一些算法题中。

2、两个变量交换

问题:不申请额外的变量实现交换两个变量。

1
2
3
4
5
6
7
public void swap(int a,int b) {
a=a^b;
// b=(a^b)^b=a
b=a^b;
// a=(a^b)^a
a=a^b;
}

3、数组中一个出现奇数次的数字

问题:一个数组中有一个数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这个数。

1
2
3
4
5
6
7
8
9
10
public void findNumberAppearOddTimes(int[] arr) {
if(arr==null || arr.length==0) {
return;
}
int xor = 0;
for(int i=0;i<arr.length;i++) {
xor ^= arr[i];
}
System.out.println(xor);
}

4、数组中两个出现奇数次的数字

问题:一个数组中有两个数出现了奇数次,其他数都出现了偶数次,怎么找到并打印这两个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public void findNumberAppearOddTimes(int[] arr) {
if(arr==null || arr.length==0) {
return;
}
int xor = 0;
for(int i=0;i<arr.length;i++) {
xor ^= arr[i];
}
// 1、运行到此可以知道:假如出现奇数次的两个数为a和b,则xor=a^b。
// 2、xor!=0可推导出:xor在第i位二进制位上为1,
// 则a和b一定存在第i位二进制位上不相同,要么a的第i位二进制位上为1,要么b的第i位二进制位上为1。
// 3、此时可以将arr中的数分为两类:第i位二进制上为1的数,第i位二进制位上不位1的数。
// 4、只接寻找xor二进制位最右侧的1:int rightOne=xor&(~xor+1);
int rightOne=xor&(~xor+1);
int xor1=0;
for(int i=0;i<arr.length;i++) {
// 数组中数&rightOne !=0 为第i位二进制上为1的数
if(arr[i]&rightOne!=0) {
// 最终结果为其中一个出现奇数次的数
xor1 ^= arr[i];
}
}
// xor和xor1再进行异或操作即得到另外一个出现奇数次的数
System.out.println(xor1+":"+xor1^xor);
}

一、单机单实例安装

笔记所有操作在centos上进行。

1、准备工作

安装一些后续步骤需要用到的包或工具。

1
yum install -y gcc wget

2、准备安装包

打开redis官网找到需要安装的版本进行下载。

1
2
wget https://download.redis.io/releases/redis-6.2.4.tar.gz
tar xf redis-6.2.4.tar.gz

3、编译安装

安装步骤在源码根目录README目录中很详细,可以按照其步骤进行即可。

1
2
3
4
5
6
7
cd redis-6.2.4 # 我的解压后目录为redis-6.2.4
# 编译源码
make
# 测试编译是否正确,可以省略
make test
# 安装可执行文件到指定目录,PREFIX即指定可执行文件的安装目录
make install --PREFIX=/opt/redis6

安装完成后PREFIX/bin目录下会有一些可执行文件redis-server等,此时配置下环境变量,把这些可执行文件添加到PATH中为后续步骤使用。

1
2
3
4
5
6
7
vi /etc/profile
# 在文件后追加下面三行内容
REDIS_HOME=/opt/redis6/bin
PATH=$PATH:$REDIS_HOME/bin
export REDIS_HOME PATH
# 刷新环境变量配置
source /etc/profile

4、redis安装为服务

把redis添加为服务,开机启动以及可以通过service xxx start来进行启动、停止和查看状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cd util
vi install_server.sh
# 注释下面的内容
#bail if this system is managed by systemd
#_pid_1_exe="$(readlink -f /proc/1/exe)"
#if [ "${_pid_1_exe##*/}" = systemd ]
#then
# echo "This systems seems to use systemd."
# echo "Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry!"
# exit 1
#fi
#unset _pid_1_exe
./install_server.sh
# 输入端口号等,按照提示输入对应内容即可

image-20210614224620485

此步骤完成后redis服务安装成功,并且过程中会启动一个redis实例,进入/etc/init.d/目录即可看到对应的redis文件,redis_6379(redis_port),此时使用service redis_6379 start/stop/status即可对redis服务进行操作。

5、bloom布隆过滤器安装

1
2
3
4
5
6
7
8
9
10
11
# 源码下载
git clone --recursive https://github.com/RedisBloom/RedisBloom.git
# 暗转cmake包
cd RedisBloom
# 编译布隆过滤器,编译时最好切换到稳定版本分支上编译,不要直接编译master分支上的代码,否则可能会出一些问题一时半会解决不了
make
# 编译完成后在RedisBloom目录下生成.so文件,拷贝到/opt/redis6文件夹下
cp redisbloom.so /etc/redis6
# 使用:启动时加载模块,注意,路径一定要写全路径
redis-server --loadmodule /etc/redis6/redisbloom.so
# 或者配置在redis的conf配置文件中:loadmodule /etc/redis6/other_module.so

—————————————————–未完待续———————————————————-

本文主要记录使用LVS搭建DR模式负载均衡的实验,第一部分高并发。只使用LVS命令方式手动搭建;第二部分高可用。使用keepalived来自动配置LVS,以及保证负载均衡器达到高可用(HA)。

第一部分、高并发

1、环境准备

准备三台虚拟机node1、node2、node3,本操作实验使用的系统为centos7系统,其中node1作为负载均衡服务器(Virtual Server,后文简称VS,其IP简称VIP),node2和node3做为服务端服务器(Real Server,后文简称为RS,其IP简称RIP),具体流程为客户端会发送请求到VS负载均衡器的VIP地址,然后VS会把对应的请求根据负载策略负载到RS端。

2、RS服务器配置

2.1、arp协议内核参数修改

该步骤为在RS端配置一个隐藏的VIP做准备。

1
2
3
4
echo 1 > /proc/sys/net/ipv4/conf/ens33/arp_ignore  #ens33为网卡名称
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/ens33/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
  • arp_ignore
    • 0:只要本地配置的有相应地址,就给予响应
    • 1:仅在请求的目标(MAC)地址配置请求到达接口上的时候,才给予响应、
  • arp_announce
    • 0:将本地任何接口上的任何地址向外通告
    • 1:试图仅向目标网络通告与其网络匹配的地址
    • 2:仅向与本地接口上地址匹配的网络进行通告

2.2、隐藏VIP配置

1
2
# IP配置到lo环回接口上,lo:2为lo网卡接口的子接口,数字随意。
ifconfig lo:2 192.168.45.100 netmask 255.255.255.255

image-20210605224206880

2.3、安装测试服务器

本次测试安装的是apache服务器,其中有一个简单的页面,请求后显示当前RS服务器的IP地址,方便实验。也可以用其他的测试应用,比如nginx,springboot的一个简单等等。

1
2
3
4
5
6
# 安装apache应用服务器
yum install -y httpd
# 配置一个简单页面
echo "from 192.168.45.10" > /var/www/html/index.html
# 启动apache,启动后访问返回的内容如下面的截图中
service httpd start

image-20210605224352368

注意:使用apache服务器需要注意一个问题,在http1.1协议时,服务器默认开启了keepalive,环境搭建完成测试的时候会出现一个问题(本来配置了轮询策略,但是在请求VS后,RS很久才会切换到另外一台),需要在httpd配置文件中关闭keepalive(keepalive off)。

3、VS服务器配置

3.1、安装LVS管理模块ipvsadm

linux系统内核默认安装了LVS负载均衡模块,即ipvs,我们只需要按住交互的接口模块,即ipvsadm即可。

1
yum install -y ipvsadm

3.1、配置VIP

1
ifconfig ens33:2 192.168.45.100/24

image-20210605225207435

3.2、配置负载均衡规则

1
2
3
4
5
6
7
8
# -A 配置VS服务,-t tcp协议,-s rr:负载调度策略轮询
ipvsadm -A -t 192.168.45.100:80 -s rr
# 配置第一台RS服务:-a 配置RS服务 -r RS的IP地址 -g DR模式,-w 权重
ipvsadm -a -t 192.168.45.100:80 -r 192.168.45.10 -g -w 1
# 配置第二台RS服务
ipvsadm -a -t 192.168.45.100:80 -r 192.168.45.10 -g -w 1
# 显示配置好的规则
ipvsadm -ln

image-20210605225705035

到此LVS高可用配置完成,访问http://192.168.45.100,刷新即可看到实验结果:上面配置的为rr轮询负载调度策略,没请求一次显示出来的IP地址不一样。

image-20210605230052138

第二部分、高可用

上面的VS配置存在一些弊端:

  • VS单点故障。
  • 配置在内存里面,关机后即消失。
  • RS健康状态无法检查。

针对上面的一些弊端,现在引入keepalived工具,实现VS高可用,配置写在配置文件里面,keepalived会自动帮我们配置VS的配置,而且keepalived还可以监控RS的监控状态,及时把存在问题的RS从VS负载规则里面剔除。

1、环境准备

需要再准备一台虚拟机node4,用来做LVS的备机,即VS服务为主备模式。

2、安装keepalived

1
yum install -y keepalived

3、配置keepalived

配置文件/etc/keepalived/keep

  • 主VS配置:只列出关键需要配置的部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
! Configuration File for keepalived
vrrp_instance VI_1 {
# 主
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
# VIP配置
192.168.45.100/24 dev ens33 label ens33:8
}
}
# VS负载规则配置
virtual_server 192.168.45.100 80 {
delay_loop 6
# 轮询
lb_algo rr
# DR模式
lb_kind DR
persistence_timeout 0
protocol TCP
# RS服务器配置
real_server 192.168.45.10 80 {
weight 1
# RS服务健康检查配置
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.45.12 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}

注意:配置好后使用过程中遇到一个坑,手动配置的VIP在同一网段上的其他机器上可以ping通,但是keepalived配置的就是ping不通,可能的原因是keepalived开启了vrrp_strict,开启后表示严格执行vrrp协议,不支持节点单播。如果配置中有这项配置,则需要把这项配置删除可顺利配置成功。

  • 备VS配置

唯一区别为state BACKUP

4、启动keepalived

1
service keepalived start

至此,配置完成,可以顺利实现LVS高并发、高可用,但是keepalived不是高可用,后续继续研究。

背景:在甲方公司进行应用压力测试,oracle数据库服务器的磁盘空间只提供了十几个G,对于要求吞吐量20000的应用来说,数据量之大可想而知,十几个G的空间只够压测几十分钟,更谈不上48小时的稳定性测试。因此只能从oracle数据库层面着手,数据库表按时间分区,然后创建一个job定时调用存储过程清理数据分区,保证压测的过程有足够的空间进行数据存储。

1、数据库表创建

1.1、创建表空间
1
create tablespace ts_test_data datafile '/data/oracle/test/ts_test_data.dbf' size 200M autoextend on;
1.2、创建表
1
2
3
4
5
6
7
8
9
10
11
12
create table cust_tb (
id varchar2(64),
name varchar2(255),
created date
)tablespace ts_test_data
partition by range(created) interval (NUMTODSINTERVAL(10, 'MINUTE'))
STORE IN (ts_test_data)
(
-- P01初始分区
partition P01 values less than (to_date('2020-12-28 00:00:00','YYYY-MM-DD HH24:MI:SS'))
tablespace ts_test_data
);

创建表根据时间字段,按照时间字段进行分区,每间隔10分钟进行一次自动分区。

2、创建清理分区存储过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
create or replace procedure delete_partition(tb_name varchar2) is
-- 分区位置编码
max_position number;
-- 循环临时变量
cnt number;
-- 分区名称
ptn_name varchar2(64);
-- 删除分区的sql语句
sql_str varchar2(255);
begin
-- partition_position位置从1开始自增
select max(partition_position) into max_position from user_tab_partitions where table_name = tb_name;
if max_position > 2 then
-- 每次清除位置从2到max_position-1上的表分区内容,1位置为初始创建的表分区,不能删除,最大一个位置的为最后一个,又可能正在写数据,也不删除
for cnt in 2..(max_position-1) loop
select partition_name into ptn_name from user_tab_partitions where table_name = tb_name and partition_position = cnt;
sql_str := 'alter table '||tb_name||' drop partition '||ptn_name||' update global indexes';
execute immediate sql_str;
end loop;
commit;
end if;
end delete_partition;

3、创建定时job

创建job,定时调用清除分区的存储过程。

1
2
3
4
5
DECLARE
job NUMBER;
BEGIN
dbms_job.submit(job,'DELETE_PARTITION(''CUST_TB'');',sysdate,'sysdate+10/1440');
END;
  • job:定时job的ID。
  • DELETE_PARTITION(‘’CUST_TB’’);:调用的存储过程,此处需要注意的是传递进去的表名必须大写,因为在分区表中存储的表名为大写。
  • sysdate:job任务开始运行的时间。
  • sysdate+10/1440:每10分钟运行一次,1440为24小时(24x60),如若为10秒运行一次,则此处为86400(24x60x60)。

4、其他关联操作

  • 表空间数据文件存储释放
1
2
3
-- 可先truncate table释放表空间后再进行操作
-- resize后的大小必须大于现有储存数据的大小
ALTER DATABASE datafile '/data/oracle/test/ts_test_data.dbf' resize 200M;
  • 删除表空间及数据文件
1
drop tablespace tablespace_name including contents and datafiles;
  • 删除定时job
1
2
3
4
BEGIN
-- 传递的参数为job的ID,可从user_jobs表查询得到
dbms_job.remove(1);
END;
  • 删除表分区及数据
1
2
-- SYS_P663分区名称,从user_tab_partitions表查询得到
alter table table_name drop partition SYS_P663 update global indexes;

influxDB

下载
1
2
#下载地址
https://portal.influxdata.com/downloads/
安装
1
2
3
# 根据官网脚本下载最新版本即可
$ wget https://dl.influxdata.com/influxdb/releases/influxdb-1.8.3.x86_64.rpm
$ sudo yum localinstall influxdb-1.8.3.x86_64.rpm
启动
1
2
3
4
5
# 启动
$ systemctl start influxdb
# 状态查看
$ systemctl status influxdb
# 设置开机启动
使用
1
2
3
4
5
6
7
8
9
10
# 运行命令即可进入influxdb进行命令交互
$ influx
#显示数据库
> show databases
# 创建数据库
> create database jmeter
# 创建用户及授权
> create user "jmeter" with password 'jmeter' with all privileges
# 查看用户
> show users

Grafana

下载
1
https://grafana.com/grafana/download
安装
1
2
3
# 根据官网脚本下载最新版本即可
$ wget https://dl.grafana.com/oss/release/grafana-7.2.1-1.x86_64.rpm
$ sudo yum install grafana-7.2.1-1.x86_64.rpm
启动
1
2
3
4
5
6
7
$ sudo systemctl daemon-reload
# 启动
$ sudo systemctl start grafana-server
# 状态查看
$ sudo systemctl status grafana-server
# 设置开机启动
$ sudo systemctl enable grafana-server
登陆访问
1
2
# 默认登陆端口为3000,默认登陆密码为admin/admin,登陆后需要更改默认登陆密码
http://localhost:3000/login
使用
  • 添加influxDB数据源

image-20201021160327320

image-20201021160505122

image-20201021160635960

  • 导入Dashboard

模板下载地址。

1
https://grafana.com/grafana/dashboards?search=influxdb

image-20201021161630624

打开下面地址后,找到对应的jmeter模板并打开,复制id,填写到下图中的输入框内,然后点击load按钮,即可加载对应的模板。

image-20201021162216205

选择第一步添加的数据源

image-20201021162307471

通过产生测试数据后即可通过Dashboard图标查看分析。

Jmeter

创建线程组

image-20201021162658997

添加Http请求

image-20201021162727799

添加influxdb的监听器

image-20201021162941301

Grafana监控数据

image-20201021163224216

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Prepare environment

Install hexo

1
$ npm install -g hexo-cli

Initialize hexo blog

1
2
3
4
# if you don't given the <floder> parameter,the blog will initialize at current floder.
$ hexo init <floder>
# install npm dependencies
$ npm install

Install necessary plugin

1
2
# The plugin can transfer chinese title to Pingyin when you generate static post files.
$ npm i hexo-permalink-pinyin --save

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server # or hexo s

More info: Server

Generate static files

1
$ hexo generate # or hexo g

More info: Generating

Deploy to github pages service

  • Configuration the github repository
1
2
3
4
deploy:
type: git
repo: #youre github repository
branch: master # deploy branch
  • Deploy
1
2
3
4
# install git deploy plugin
$ npm install hexo-deployer-git --save
# deploy
$ hexo deploy #or hexo d

More info: Deployment