自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

墨玉浮白的博客

用于学习记录、技术提升

  • 博客(281)
  • 收藏
  • 关注

原创 RocketMQ NameServer网络通信架构(基于Netty)

初始化Netty是负责监听、处理Broker和客户端发送的网络请求的,NameServer通过9876这个端口接收来自Broker、客户端的网络请求,如Broker注册自己、客户端拉取Broker路由数据等。在构建好NamesrvController后,会通过start方法来启动这一核心组件。首先要初始化NamesrvController//初始化NamesrvControllerboolean initResult = controller.initialize();在这个方法内,会构建Net

2021-07-05 15:17:02 258

原创 RocketMQ NameServer启动要初始化哪些参数

distribution/bin/mqnamesrv中启动NameServer进程的命令:sh ${ROCKETMQ_HOME}/bin/runserver.sh org.apache.rocketmq.namesrv.NamesrvStartup $@这行命令执行了runserver.sh,以此启动了NamesrvStartup这个Java类JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MXX:MaxMetaspaceSize=320

2021-07-05 14:03:45 837 2

原创 Kafka Sender线程如何发送数据

文章目录1.内存缓冲中的Batch,如何被判定可发送出去2.标识那些元数据未拉取成功的3.检查筛选出来的Broker是否可以发送数据3.1 元数据是否已经就位3.2 是否可以发送请求3.3 跟Broker建立连接3.3.1 初始化SocketChannel3.3.2 发起连接请求3.3.3 将SocketChannel缓存起来3.4 筛选Broker4.将Broker分组5.淘汰超时的Batch6.为Batch以Broker为单位,构建Request7.将构建好的Request请求发送出去番外篇:完成最终的

2021-05-13 11:51:51 425

原创 谈谈对Kafka Accumulator的理解

文章目录前期准备1.获取分区队列Deque2.尝试将消息放到batch中3.基于Buffer Pool,给batch分配一块内存3.1 如何基于缓冲池中的ByteBuffer,复用内存空间3.2 不断申请内存导致可用内存被耗尽咋办?4. 基于double-check模式,再次尝试tryAppend4.1 一条消息是如何按照二进制协议写入到Batch中的ByteBuffer中的4.2 频繁写入消息,如何进入已有的分区的batch中?4.3 如果1个Batch被写满了,如何申请内存构建下一个Batch?5.总结

2021-05-07 16:03:44 572

原创 一条消息是如何按照二进制协议写入到Batch中的ByteBuffer中的

double-check模式中会将消息放到Batch中://将消息放到batch中去FutureRecordMetadata future = Utils.notNull(batch.tryAppend(timestamp, key, value, callback, time.milliseconds()));实际调用的是MemoryRecords的的append方法,将消息写入到MemoryRecords的ByteBuffer中://调用MemoryRecord#append方法,将消息放入

2021-05-07 13:17:38 159

原创 基于double-check模式尝试将消息放到batch中

多线程并发获取Deque,但只会有一个人会new。然后就会对获取到的Deque加锁,并尝试将消息放入到获取到的Deque的已有的batch中: //对分区队列加锁后,尝试将消息放到队列中的已有的batch中 synchronized (dq) { if (closed) throw new IllegalStateException("Cannot send after the produ

2021-05-07 11:09:12 158 2

原创 Kafka如何基于CopyOnWrite实现线程安全的Deque构建

执行getOrCreateDeque方法,拿着topic的partition,就去拿分区队列Deque(有就拿,没有就创建)。private Deque<RecordBatch> getOrCreateDeque(TopicPartition tp) { //分区作为key,从CopyOnWriteMap中拿分区队列Deque //如果有Deque就拿,没有就创建 Deque<RecordBatch> d = this.batches

2021-05-07 10:56:49 300

原创 Kafka将消息发往内存缓冲区

KafkaProducer是多线程并发安全的,多线程环境下也不会导致数据错乱。//将消息添加到内存缓冲里去,RecordAccumulator组件负责的RecordAccumulator.RecordAppendResult result = accumulator.append(tp, timestamp, serializedKey, serializedValue, interceptCallback, remainingWaitMs);首先要从内存缓冲区中找出这个partition对应的De

2021-05-03 16:17:31 990

原创 Kafka ProducerRecord的分区路由策略

分区路由策略把消息、序列化的key、序列化的value、元数据都传参给partition()方法。首先要获取消息的分区号://获取消息的分区Integer partition = record.partit

2021-04-29 21:18:30 833

原创 Kafka如何对Topic元数据进行细粒度的懒加载、同步等待?

首先确保Topic的元数据可用,否则消息根本没法往外发。如果以前从没加载过Topic元数据,就会在doSend发送消息时调用waitOnMetadata方法在此同步阻塞住,等待连接Broker成功后拉取元数据。max.block.ms决定了调用send()方法时,最多会被阻塞多长时间。send在一些异常情况下:拉取Topic元数据,连接不到Broker数据放到内存缓冲区,但内存缓冲区已经满了经历这段时间后,就必须得返回了。首先会判断目标Topic的元数据是否已经被加载过了。如果没有,就会把该T

2021-04-29 18:05:46 464

原创 客户端发送消息时,源码运行的大致流程

send消息: @Override public Future<RecordMetadata> send(ProducerRecord<K, V> record, Callback callback) { // 如果拦截器为null,就直接拿封装的ProducerRecord //否则就动用拦截器,对发送的消息进行拦截 ProducerRecord<K, V> interceptedRecord = this

2021-04-29 14:56:30 86

原创 KafkaProducer初始化时,是否会拉取集群元数据?

debug看一下://核心行为:初始化时,直接调用Metadata组件的方法,从Broker上拉取1次集群元数据,每隔5min刷新一次//在发送消息过程中,如果没找到某个Broker的元数据,也得去拉取一次this.metadata.update(Cluster.bootstrap(addresses), time.milliseconds());会将addresses传进去,并返回包装好的Cluster: //addresses就是我们配置的Broker:[localhost/127.0

2021-04-29 11:33:17 308

原创 Kafka Cluster元数据在客户端缓存采用的数据结构

看Cluster类的数据结构1个Node就代表1个Broker,也就代表了1台机器:private final List<Node> nodes;Set维护了Kafka没有被授权访问的Topic列表://没有被授权访问的Topic列表private final Set<String> unauthorizedTopics;由此可见Kafka支持权限控制,如果客户端没有授权访问某个Topic,它就会被放在此处对于Cluster,还通过一些数据结构,维护了客户端缓存的t

2021-04-29 11:30:25 202

原创 KafkaProducer初始化时涉及到哪些核心组件?

执行以下代码:KafkaProducer<String,String> producer = new KafkaProducer<String,String>(props);走构造:public KafkaProducer(Properties properties) { this(new ProducerConfig(properties), null, null);}先把我们的配置拿出来://拿到我们设置的参数Map<String, Object&

2021-04-29 10:35:54 266

原创 Spark自定义累加器

如果需求不仅仅是简单的对i累加,而是操作对象,那就得自定义累加器。首先定义好样例类case class PersonInfo(var personNum: Int, var ageSum: Int)自定义的累加器,需要继承AccumulatorV2,泛型分别表示进来的和出去的类。需要重写6个方法:isZero:每个partition内的累加器是否有初始值copy:复制累加器,Driver端到各个partitionreset:每个partition内,对象的初始值add:每个partition

2021-04-27 10:41:34 830

原创 Worker启动Executor源码

给Executor划分好资源后,Worker就要按此来启动Executor了。资源划分完毕后,会返回每个Executor实得多少core的数组,然后就是循环可用的Worker节点,给Executor划分资源。val assignedCores = scheduleExecutorsOnWorkers(app, usableWorkers, spreadOutApps)// Now that we've decided how many cores to allocate on each worker,

2021-04-26 12:36:56 147

原创 Spark Application资源调度源码

master的receive方法接收到RegisterApplication类型的消息,就要给application划分资源了。 //Driver 端提交过来的要注册Application case RegisterApplication(description, driver) => // TODO Prevent repeated registrations from some driver //如果Master状态是standby 忽略不提交任务

2021-04-25 15:18:33 120

原创 Spark任务提交源码

SparkSubmit的main方法执行,首先要设置一些参数://设置参数val appArgs = new SparkSubmitArguments(args)接着会进行模式匹配,匹配到submit,调用submit方法,做了两件事: //以下方法prepareSubmitEnvironment 返回四元组,重点注意childMainClass类 这里以standalone-cluster为例 // childMainClass:未来启动Driver的main class是谁

2021-04-25 04:08:24 202

原创 Spark Worker启动源码

worker的启动流程和master的启动流程相同,区别就是在worker启动完成后,要向Master注册、汇报资源。在Worker的onStart()方法中会调用registerWithMaster()方法来向Master注册: private def registerWithMaster() { // onDisconnected may be triggered multiple times, so don't attempt registration // if there ar

2021-04-24 11:40:08 142

原创 Spark Master启动源码分析

文章目录一、RPC通信环境二、注册EndPoint底层使用netty通信,先准备出RpcEnv环境来做通信架构,创建:收消息结构、处理消息结构。RpcEnv会处于一直启动的状态,不死不灭。Master启动的时候,会把通信地址(也叫通信邮箱,EndPoint)注册到RpcEnv中。别人想跟Master通信,只需要发送到RpcEnv中,Master的EndPoint刚刚才向RpcEnv注册,于是RpcEnv接收到别人的通信请求,并立刻发送消息给Master。首先,RpcEnv要先创建自己的Rpc环境和En

2021-04-24 10:56:19 156

原创 Spark任务提交流程

文章目录1.Standalone-Client2.Standalone-cluster3.Yarn-Client模式4.Yarn-Cluster1.Standalone-Client[root@node4 bin]# ./spark-submit --master spark://node1:7077 --class org.apache.spark.examples.SparkPi ../examples/jars/spark-examples_2.11-2.3.1.jar 1001.Cl

2021-04-21 09:09:14 2626 3

原创 用Spark实现简单的单词统计

用Scala实现RDD(可以简单理解为是一个list集合,里面放的就是读到的一行一行的数据)是spark中非常核心的内容,只有通过SparkContext才能创建出来RDD。package com.husky.sparkimport org.apache.spark.rdd.RDDimport org.apache.spark.{SparkConf, SparkContext}object SparkWordCount { def main(args: Array[String]): Un

2021-04-18 20:48:25 1869

原创 Redis哨兵机制

文章目录1.分布式哨兵的作用2.sdown和odown的转换机制3.哨兵集群的自动发现机制4.哨兵自动纠正slave5.slave ---> master选举算法哨兵本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。判断一个master node是宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题1.分布式哨兵的作用集群监控,监控master、slave进程是否正常工作故障转移,master故障(哨兵按照过半机制),自动转移到Slave上。并通知Client新的master地

2021-04-16 10:23:06 139

原创 Redis主从复制原理

文章目录1.主从复制原理2.断点续传3.无磁盘化复制1.主从复制原理启动slave时,它会给master发送PSYNC命令。如果slave第一次连接master,就触发full resynchronization;如果是重新连接,master仅仅会复制给slave缺失的部分。开始full resynchronization的时候,master会启动一个后台线程,开始生成一份RDB快照文件,同时还会将从客户端收到的所有写命令缓存在内存中。RDB文件生成完毕之后,master会将这个RDB发送给slav

2021-04-15 16:57:47 102

原创 RDB和AOF的持久化配置

文章目录RDB相关1.如何配置RDB持久化2.RDB持久化机制的工作流程3.基于RDB的数据恢复AOF相关1.如何配置AOF持久化2.AOF持久化机制的工作流程3.破损文件修复AOF和RDB同时工作RDB相关1.如何配置RDB持久化在redis.conf文件中:# 设置检查点save 900 1save 300 10save 60 10000# 配置 dir 指定 rdb 快照文件的位置dir /var/redis/6379# 配置 dbfilename 指定 rdb 快照文件的名称

2021-04-15 11:33:20 280

原创 数据如何从HBase读到MR

TableMapReduceUtil.initTableMapperJob是用来对内输入的,传递的参数之一,就是输入格式化类TableInputFormat.class,且会进行set操作:job.setInputFormatClass(inputFormatClass);TableInputFormat的父类TableInputFormatBase会创建TableRecordReader:if (trr == null) { trr = new TableRecordReader();}S

2021-04-12 08:41:07 114

原创 数据如何写入到HBase

TableMapReduceUtil.initTableReducerJob是用来向外输出的,传递的参数之一,就是tableName。该方法做的最主要的事,就是设置输出格式化类、配置表。 //设置输出格式化类 job.setOutputFormatClass(TableOutputFormat.class); if (reducer != null) job.setReducerClass(reducer); //输出到table中,table就是传进来的表名 con

2021-04-12 08:32:04 757

原创 垃圾回收机制

文章目录引入一、什么情况下JVM内存中的对象会被垃圾回收1.1 哪些变量引用的对象不能被回收?1.2 Java对象的引用类型1.3拯救者finalize()方法1.4 垃圾回收总结二、分代模型2.1 对象在JVM内存中的分配、流转2.2 内存分配总结三、垃圾回收算法3.1 复制算法四、垃圾回收器4.1 ParNew4.2 CMS引入以下面代码为例:public class Kafka { public static void main(String[] args) { load

2021-04-09 15:40:28 199

原创 JVM内存区域划分

文章目录1.存放类的方法区2.执行代码指令的程序计数器3.Java虚拟机栈4.堆内存5.其他内存区域总结1.存放类的方法区主要放的是 从“.class”加载进来的类public class Kafka { public static void main(String[] args) { ReplicaManager replicaManager = new ReplicaManager(); }}2.执行代码指令的程序计数器coder能看懂“.java”文件,

2021-04-08 10:01:18 141

原创 类加载

文章目录类加载过程1.加载2.验证3.准备4.解析5.初始化类加载器双亲委派机制“.java文件” 编译成“ .class字节码文件”,通过类加载器交给JVM运行。JVM会基于自己的字节码执行引擎,来执行加载到内存中的各种类。类加载过程一个类从加载到使用,要经历 加载—>验证—>准备—>解析—>初始化—>使用—>卸载1.加载代码中用到这个类了,类加载器就会将其加载到JVM内存,main()方法作为入口开始执行。public class User { p

2021-04-08 09:10:42 118

原创 LiveData原理分析

文章目录简述LiveData原理1.订阅、绑定2.setValue发送消息3.总结简述LiveData是一个可被观察的数据容器类,它将数据包装起来,使数据成为被观察者。当数据发生改变时,观察者能够及时得到通知。又是一个典型的观察者模式!ViewModel用来存放页面所需要的数据、和数据相关的处理逻辑(在ViewModel中对数据进行加工、获取),站在页面的角度上,它并不关心ViewModel的业务逻辑,只关心需要展示的数据是啥。它希望在数据发生改变时,能够及时的得到通知并作出更新。而LiveData的

2020-10-14 14:50:40 1315 1

原创 LifeCycle原理分析

文章目录简述LifeCycle的原理简述解耦是永恒不变的话题,但是又不得不做。平时在onCreate方法中初始化,在onDestory中回收资源,这样会使页面和组件之间的耦合度增加,不这样做又会造成内存泄漏。我们希望对组件的管理,不仅仅是依赖生命周期函数的管理方法。LifeCycle正是因此出现的,组件就能够在内部自己管理自己的生命周期,从而降低模块间的耦合度,并降低内存泄漏的可能性。LifeCycle的原理LifeCycle是通过观察者模式,实现对页面生命周期的监听。Jetpack提供了两个类:

2020-10-14 10:49:40 884

原创 解析RecyclerView的缓存机制

文章目录复用:layoutChunk(recycler, state, layoutState, layoutChunkResult)1. getChangedScrapViewForPosition方法--->mChangedScrap2.getScrapOrHiddenOrCachedHolderForPosition--->mAttachedScrap、mCachedViews3. getScrapOrCachedViewForId--->mAttachedScrap、mCached

2020-07-16 15:50:39 634

原创 事件分发机制并不是洪水猛兽

当MotionEvent产生后,系统总归要将其传递到某个View,这个过程就是事件分发。事件分发机制离不开3个重要方法:dispatchTouchEvent(分发)、onInterceptTouchEvent(拦截,在dispatchTouchEvent中调用。需要注意,View中没有该方法)、onInterceptTouchEvent(处理事件,在dispatchTouchEvent中调用。)这3个方法相爱相杀,紧密关联。ViewGroup收到点击事件后,它的dispatchTouchEvent方法首先

2020-07-13 18:23:21 246

原创 对ViewPager的理解

文章目录设置wrap_content无效?

2020-07-08 18:10:58 1689

原创 解析SharedPreferences

文章目录简介一、文件保存二、SP创建三、SP数据加载四、getxxx()操作五、putXXX()操作5.1 commit &&apply5.2 apply简介sp作为轻量级存储,数据最终都是以xml的形式进行存储的。一、文件保存SharedPreferences config = getSharedPreferences("config", Context.MODE_PRI...

2020-04-30 13:13:06 523

原创 9.0适配刘海屏

刘海屏适配,就是不让刘海遮挡住应用程序,不影响应用程序的正常使用。竖屏情况下,系统会根据刘海的高度,响应调整状态栏的高度。因此,刘海对竖屏模式没有影响。可是横屏模式下,刘海区域就会变成一条大黑边。Android 9.0系统中提供了3种layoutInDisplayCutoutMode属性来允许应用自主决定该如何对刘海屏设备进行适配:①LAYOUT_IN_DISPLAY_CUTOUT_M...

2020-04-27 15:49:17 698

原创 沉浸式学习

沉浸式就是利用系统状态栏,将背景图片延伸至系统状态栏区域内,效果就是和游戏应用画面那样。Action1 隐藏状态栏和ActionBar仅仅是隐藏状态栏和ActionBar,只是粗暴的隐藏了而已//获取当前界面的DecorView View decorView = getWindow().getDecorView(); //表示全屏,即隐藏状态栏 int option ...

2020-04-27 10:36:56 3283

原创 黑白屏解决方案

文章目录一、黑白屏原因二、解决方案2.1 修改AppTheme2.2 自定义AppTheme一、黑白屏原因在app启动流程中,当系统加载并启动app时,需要耗费一定的时间。即使这个时间非常短,但是用户依旧会感觉点击App图标的“延迟”。为解决这一问题,Google在App创建的过程中,先展示一个空白页面,让用户体会到点击图标后立马就会有响应。而这个空白页面的颜色,就是根据我们清单文件中配置的主...

2020-03-27 21:59:09 894

原创 刘海屏适配

文章目录一、简述二、实现三、手机厂商的适配四、工具类一、简述Android官方9.0刘海屏的适配策略是:如果非全屏模式(有状态栏),则app不受刘海屏的影响,刘海屏的高就是状态栏的高;如果全屏模式,app未适配刘海屏,系统会对界面做特殊处理,竖屏向下移动,横屏向右移动。二、实现必须在setContentView方法前调用 requestWindowFeature(Window.FEATU...

2020-03-18 15:40:26 524

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除