架构图:
一、环境准备
1,3台nginx做web,两台nginx做负载均衡器,使用keepalived实现双vip,3台kafka,3台zookeeper
2,nginx搭建:
①使用yum安装好epel源(epel源相当于一个第三方库)和nginx
yum install epel-release -y
yum install nginx -y并启动nginx
启动:systemctl start nginx
设置开机自启
systemctl enable nginx
②编辑配置文件(一般来说yum安装的软件都在/etc同名文件夹下)
cd /etc/nginx/
#配置文件修改
vim nginx.conf
将
listen 80 default_server;
修改成:
listen 80;
#####退出保存之后,新建/etc/nginx/con.d/sc.conf
vim /etc/nginx/conf.d/sc.conf
server {
listen 80 default_server;
server_name www.sc.com;
root /usr/share/nginx/html;
access_log /var/log/nginx/sc/access.log main;
location / {
}
}
###进行语法检测:
nginx -t
###语法无误,重新加载nginx
nginx -s reload
安装kafka和zookeeper(使用的kafka版本是2.12,依赖于zookeeper,kafka里有集成的zookeeper。但是不好用,一般重新下载了) ①安装安装java:yum install java wget -y(安装java的目的是zookeeper是用java写的) 安装kafka: wget https://mirrors.bfsu.edu.cn/apache/kafka/2.8.1/kafka_2.12-2.8.1.tgz 解包: tar xf kafka_2.12-2.8.1.tgz 使用自带的zookeeper集群配置 安装zookeeper: wget https://mirrors.bfsu.edu.cn/apache/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz ②配置kafka: 2、配置kafka 修改config /server.properties: 让每台机器的id必须不一样,是一个唯一的整数 broker.id=0 服务启动监听,必须写主机名,但是解析的时候用的时ip,所以我们必须在/etc/hosts下配置好主机名和ip的映射关系 listeners=PLAINTEXT://nginx-kafka01:9092 #因为kafka依赖于zookeeper,把zookeeper配置好才能启动kafka zookeeper.connect=192.168.0.94:2181,192.168.0.95:2181,192.168.0.96:2181 #设置日志存放位置 ############################# Log Basics ############################# # A comma separated list of directories under which to store log files # log.dirs=/data ③配置zookeeper: 进入/opt/apache-zookeeper-3.6.3-bin/conf(加入zk的conf目录) #进入conf目录,启动得时候只认zoo.cfg,(zoo_sample.cfg 为模板文件命令) cp zoo_sample.cfg zoo.cfg #修改zoo.cfg, 在最底下添加如下三行: #server后面得1,2,3也随便写,但是每台要对应唯一的ip,这三个server就是zookeeper的集群 server.1=192.168.0.94:3888:4888 server.2=192.168.0.95:3888:4888 #3888和4888都是端口 一个用于数据传输,一个用于检验存活性和选举 # 然后创建/tmp/zookeeper目录 , # 在目录中添加myid文件,文件内容就是本机指定的zookeeper id内容, #宣告一下我的id是多少, # 如:在server.1=192.168.0.94机器上(每台机器上echo对应的数字) # echo 1 > /tmp/zookeeper/myid ④zk和kafka的启动: zk的启动 进入到bin目录下./zkServer.sh start 之后./zkServer.sh status,如果有一个leader两个follower就启动成功了 启动kafka # [root@kafka03 kafka_2.12-2.8.1]# bin/kafka-server-start.sh -daemon config/server.properties ⑤测试 1,创建topic #在kafka的bin目录下敲,topic后面是你创建的主题 # bin/kafka-topics.sh --create --zookeeper 192.168.173.139:2181 --replication-factor 3 --partitions 3 --topic sc #查看topic # bin/kafka-topics.sh --list --zookeeper 192.168.0.95:2181 #创建生产者,这是在没有filebeat的情况下手动创建了一个生产者 # [root@localhost kafka_2.12-2.8.0]# bin/kafka-console-producer.sh --broker-list 192.168.0.94:9092 --topic sc # 创建消费者(消费一下) # [root@localhost kafka_2.12-2.8.0]# bin/kafka-console-consumer.sh --bootstrap-server 192.168.0.96:9092 --topic sc --from-beginning#from beginning意思是从最开始进行消费
部署file beat:
1、rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
2、编辑/etc/yum.repos.d/fb.repo文件
[elastic-7.x]
name=Elastic repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
3、yum安装
yum install filebeat -y;
rpm -qa |grep fileberat #可以查看filebeat有没有安装 rpm -qa 是查看机器上安装的所有软件包 rpm -ql filebeat 查看filebeat安装到哪里去了,牵扯的文件有哪些
4、设置开机自启
systemctl enable filebeat
####配置
#先把filebeat.yml备份一份filebeat.yml.bak,再清空filebeat.yml,把下面的代码粘过去
# 修改配置文件/etc/filebeat/filebeat.yml
# filebeat.inputs:
# - type: log
# # Change to true to enable this input configuration.
# enabled: true
# # Paths that should be crawled and fetched. Glob based paths.
# paths:
# - /var/log/nginx/sc/access.log #这里写你的nginx日志存放的位置
# #==========------------------------------kafka-----------------------------------
# output.kafka:
# hosts: ["192.168.229.139:9092","192.168.229.140:9092"]#这里写出kafkaip
# topic: nginxlog #创建的topic
# keep_alive: 10s
在kafka的bin目录下:
#创建主题nginxlog,与filebeat里面的topic一样,这样才能获取到nginx的里数据
# bin/kafka-topics.sh --create --zookeeper 192.168.173.141:2181 --replication-factor 3 --partitions 1 --topic nginxlog
# #启动服务:
# systemctl start filebeat
##验证日志有没有到kafka
#就看能不能消费到日志(此时的生产者是filebeat)
一些原理和小点:
一、如何保证数据的一致性:
①生产者可以通过request.required.acks来设置ack的值:
ack为0:生产者只管发送数据,不接受响应就发下一条
ack为1:也是默认值;leader收到之后就会给生产者发送响应
ack为-1:等待ISR列表中的每一个副本都收到之后再给生产者发送响应
②消费者消费数据时引入了High Water Mark机制,只能消费ISR列表中偏移量最小的副本的消息数量
二、消费者如何知道自己消费到哪里了?
消费的时候会记录自己的消费偏移量
①偏移量可以写在本地,消费一条,记录一条
②kafka中_consumer_offset主题也是用来保存偏移量的
三、生产者一般跟leader打交道,但是怎么去区分这个partition是leader还是follower呢?
谁是leader谁是follower这个信息保存在zookeeper里面;
生产者发送消息的时候,随意挑选任意一台都可以,会有协商,这个broker会返回给你副本leader的信息,生产者再去跟leader交互;
四、数据的存储目录:
文件夹:<topic_name>-<分区>
每一个partition的数据都是由很多个segment存储,每一个segment有一个index和log文件组成;
保存在多个segment的好处是方便清理 ,一个在清理其余的还可以继续往里面写;
五、zk在kafka中的作用
①保存kafka的元信息:topic,副本,partition
②选举出kafka的controller:管理kafka的副本的leader和follower的选举和同步
Controller与Zookeeper进行交互,获取与更新集群中的元数据信息。其他broker并不直接与zookeeper进行通信,而是与 Controller 进行通信并同步Controller中的元数据信息。
Kafka集群中每个节点都可以充当Controller节点,但集群中同时只能有一个Controller节点,Broker 在启动时,会尝试去 ZooKeeper 中创建 /controller 节点。Kafka 当前选举控制器的规则是:第一个成功创建 /controller 节点的 Broker 会被指定为控制器
六、zookeeper集群是有个选举机制:
一致性算法(zab)少数服从多数原则,票数过半的当选为leader(>=n//2+1)
客户端连接任何一台zk都可以操作,但是数据新增修改等事务必须在leader上运行,客户端如果连接到follower上进行事务操作,follower会返回给leader的ip,最终客户端还是在leader上操作,查询操作可以直接连接follower进行查询操作,但是写一定要连接leader
数据的同步,只要过半节点同步完成,表示数据已经提交,zookeeper不是强一致性的,属于最终一致性(最终会同步完的)
每zookeeper集群要有过半机器存活才能用,zk集群的节点数一般都设置为基数,方便选举
七、filebeat里要注意的
①配置文件的输出写了多个,导致服务一直启动不了,后来查看日志和资料,了解到filebeat只能有一个输出,后面将另一个输出关掉就好了,
②因为yml格式严谨,缩进要注意,不然文件不能生效,
八、Topic是一个存储消息的逻辑概念,可认为为一个消息的集合。物理上,不同Topic的消息分开存储,每个Topic可划分多个partition,同一个Topic下的不同的partition包含不同消息。每个消息被添加至分区时,分配唯一offset,以此保证partition内消息的顺序性。