- 博客(118)
- 问答 (10)
- 收藏
- 关注
原创 clickhouse小结
ClickHouse特征列式存储可以读取很快数据压缩基于列式存储的特征,数据都是特征相似连续存储的,因此可以使得压缩去重效果较好,从而减少数据传输的IO开销向量化执行支持CPU寄存器层面的并行,向量化执行简单理解就是基于CPU指令集的并行执行,实现单条指令来操作多条数据,通过SSE4.2指令集实现向量化执行多线程与分布式1、数据表有分区的概念,因此可以基于分区做并行操作2、纵向扩展:一份数据可以分成不同的分片存储在不同的机器上,可实现数据的分布式存储扩展与并行计算。3、横
2022-04-28 10:41:25 315
原创 Flink源码剖析之JobGraph的生成
背景其实,以前编写flink代码的时候,模式比较固定,不管你中间过程如何花里胡哨,开头总要有一个获取上下文环境,最后总要有一个:env.execute(),之前只是知道这个方法,会在job提交的时候,用于获取job的计算流程图,但是我一直很好奇,到底是什么时机生成的呢?源码剖析创建JobGraph我们知道,提交任务的时候,是要有一步获取Job的JobGraph的: /** * Creates a {@link JobGraph} with a specified {@link Job
2022-03-23 16:56:15 1926 1
原创 FlinkSQL平台化之路-StreamX提交源码剖析
前言背景在公司里做实时计算开发,之前大部分job都采用的是基于java的streaming编程方式进行的,这样的好处很明显:足够灵活,可以应对各种复杂的实时分析场景,但缺点也很明显:上手存在门槛,需要懂code,如果是一个逻辑简单的计算需求,用code整体编写起来的方式,会让整个流程也略显笨重…于是我开始想,目前的公司流式开发的流程也趋于稳定了,而对于后续接近来的需求,如果可以用SQL解决,就尽可能用SQL解决,这样无论是从开发成本或者是未来如果版本升级造成的迁移成本都会有一个明显的降低。而如果单纯通
2022-03-23 16:52:03 3866 2
原创 云原生之K8S-01-简介与基本概念
集群编排的困难现代服务大多数都不是单点的,更多的是各种微服务,充斥着各种分布式的分布特点,对应docker的容器的话,一个服务实例就是一个容器,但随着节点一直增多,docker对于这些容器的部署难度也变得棘手了起来。容器编排工具比较docker-compose是docker官方提供的对docker多容器进行编排管理,但存在局限性,只能对单机内的多容器进行编排。Docker-Compose 是用来管理你的容器的,有点像一个容器的管家,想象一下当你的Docker中有成百上千的容器需要启动,如果一个一
2022-02-28 11:23:22 23249
原创 算法小记-SegmentTree
线段树(区间修改树)内部结构是一个数组。对外提供三个接口:add(L,R,V):在LR范围上的位置上的所有的数都加上某个V值update(L,R,V):在LR范围上的位置上的所有的数都更新成某个V值getsum(L,R):获取LR范围上的所有的数的累加和如何比较快的实现上述方法?假设数据规模是N,使其每个方法的操作时间复杂度都达到O(logN)的级别。暴力常规实现public static class Right { public int[] arr; public Righ
2022-01-27 10:01:02 634
原创 算法小记-IndexTree
前言在对一个数据集进行一些例如区间【L,R】求和的问题的时候,想通过一个比较快的数据结构来完成,可以使用indexTree,它可以达到O(logN)的时间复杂度。时间复杂度O(logN)算法思想构建一个help数组作为一个help数组,有如下特点:1、help数组的有效位置从1位置开始2、采用“配对”的方式在位置上存放值,因此以图上为例,我们来描述一个这个过程:1:1位置上只有自己,因此只存放1位置的值2:之前有一个1位置,所以与2位置配对,组成一对,所以此位置存放1,2位置的值3:
2022-01-11 16:45:02 458
原创 一次TOPN需求带来的历险-与Flink SQL的爱恨情仇
背景最近接到一个需求,算是一个比较常见的需求,我们公司的业务会涉及到直播,因此直播自然避免不了高并发的房间内发消息,因此业务端给出的需求就是:实时得为业务端提供近10s内的每个房间的消息总数TOP20, 业务端会根据TOP前几进行相应的限流的一系列操作。思考其实接到这个需求,我的思考实现方式是这样的:1、先求出每个房间的近10s的消息总数2、将第一步得到的每个房间的近10s的消息总数进行汇总,排序,从而得出最终结果: 近10s内,消息数TOP10的房间是哪些可以看到上面的每一步,都对应一个时间范
2021-12-10 15:05:07 1713 1
原创 基于Prometheus的flink性能监控小坑记录
背景公司内的flink集群跑了挺长一段时间了,一直也没有对其进行一个比较完整的监控,最近打算着手做这件事情,经过网上的调研,目前公司采用的部署模式是per-job模式,最终选用了基于prometheus,把job指标推送到中间网关的pushgateway上面,然后prometheus去抓取pushgateway上面的信息,从而实现对flink做性能监控,最后通过Grafana进行展示。问题在接入过程中,发现了一个问题: 我感觉prometheus的机制有点蠢!!!为啥这么说?pushgateway
2021-11-26 16:33:50 2199
原创 java中的lambda可以序列化吗?
java中的lambda可以序列化吗?这个问题之前一直也没想过,其实主要也是之前从来没有遇到过需要序列化它的情景,直到。。。我在开发flink作业的时候,因为一些需求,需要传入一个自定义的过滤器,而自然而然就直接使用这种lambda写一通函数式编程又爽又好用,但启动后确是:直接一手序列化报错给我整懵逼了, 恩? 原来lambda是不能序列化的吗,一般来说,一个普通的实体类,只需要给类实现一个Serializable的接口标明,就可以参与序列化了,但这种lambda怎么给接口呀?但是我脑海中突然闪
2021-11-11 17:25:07 1745 2
原创 设计模式之代理模式静态代理,动态代理以及源码分析,CGLIB
最近在系统的啃一啃设计模式相关的东西, 其中对代理模式尤为感兴趣(主要也觉得它很神奇),而且代理模式的用途实在是太广泛了说代理之前,从一个需求入手:有一个tank类,作为一个坦克,肯定可以移动,也就是肯定会有一个移动的方法,我想记录一下它的move方法的执行时间,该怎么做?interface Movable { void move();}public class Tank implements Movable { /** * 模拟坦克移动了一段儿时间 */
2021-10-26 10:55:46 120
原创 KAFKA那些事-07-从KAFKA总结分布式下的发送和连接
分布式模型下的客户端应用运行的关键?分布式下,通常有多个角色进行互相协调。因此作为一个分布式角色来说,首先要解决的就是如何和其他分布式角色进行通信。对于客户端而言,首先需要明确集群的信息,以及如何进行连接,因此也涉及到具体使用到的IO模型是什么?如下是kafka producer发送一条消息需要进行的操作:1、拉取集群元数据2、底层利用NIO建立sokcet连接进行向指定节点进行发送信息。分布式模型下的服务端应用运行的关键?作为服务端来说,更关心的是如何更好的接收和管理众多的连接,以及对连接
2021-10-26 10:32:51 792 1
原创 工作杂记-关于IOS通过Safari使用https域名访问的坑
1、背景为了测试环境与线上环境前端代码的接口访问地址编写统一,我们公司不直接使用ip进行访问,而是统一使用域名进行访问, 在本地开发测试时,通过内网DNS服务器解析到测试环境,当线上环境时,则解析到公网环境。其他端都没有什么问题,但维度使用iphone通过safari访问时,然后Safari上就一直无法访问网站,Chrome没问题。Safari上报错内容就是:…连接服务器中断…2、查找过程首先根据Safari报错内容找,什么都找不到然后看Nginx的报错日志error.log,发现报worke
2021-09-14 11:14:09 2008
原创 KAFKA那些事-06-KAFKA Producer基于源码分析的参数配置调优
Producer配置分析Properties conf = new Properties();//设置ACK级别: 0,1,-1conf.setProperty(ProducerConfig.ACKS_CONFIG,"0");//Key序列化器conf.setProperty(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());//Value序列化器conf.setProperty(P
2021-08-18 10:46:38 380
原创 KAFKA那些事-05-KAFKA的索引文件分析、ACK不同级别的现象、基于时间戳的索引
KAFKA中的索引与数据文件的分析创建topic来到KAFKA存储目录,发现已经有了两个分区的数据:进到0号分区的文件夹:发现有.log结尾的数据文件,.index结尾的偏移量索引文件,.timeindex结尾的时间戳二级索引文件但我们发现,我们现在还没有写入消息,但两个索引文件就已经有了10M的大小,这是为何?这是因为kafka对索引文件使用的是mmap映射,已经预分配好了10M的磁盘块大小的空间,通过lsof查看kafka进程号观察这个细节:可以看到SIZE/OFF的位置上,确实已
2021-07-21 15:11:04 478
原创 KAFKA那些事-04-KAFKA的元数据细节、消息存放机制、零拷贝发送、分布式集群副本同步
KAFKA的元数据与zookeeperkafka的元数据是交给zookeeper来管理的。假设我们有topic :ooxx, 副本数为2,主副本在id为3的broker上,另一个副本在id为1的上面。 此时,只有主副本有读写能力,从副本只能备着。前面我们说过,kafka集群会选出一个broker作为controller,这个选举是借助zookeeper来完成的,zookeeper本质是通过让它们抢占一个临时节点,谁抢到谁就是controller。如图下:通过zookeeper的kafka路径中
2021-06-15 10:19:21 958
原创 KAFKA那些事-03-JAVA API实操(生产者、消费者属性配置,偏移量提交方式)
Producerproducer是面向broker的,然后向指定的toopic进行发送数据,相同key去到同一分区。初始化配置String topic = "msb-items";Properties p = new Properties();p.setProperty(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "node02:9092,node03:9092,node01:9092");//kafka 持久化数据的MQ 数据-> byte[],
2021-06-15 10:11:50 218
原创 KAFKA那些事-02-KAFKA搭建、消息拉取和offset更新策略
1、准备zookeeper环境2、搭建KAFKA环境编辑server.properties,注意填写zk地址的时候,比较好的做法是在zookeeper地址后加上一个路径:zookeeper.connect=node02:2181, node02:2181, node03:2181/kafka以及要保证每个broker.id保证不同。3、启动kafka/opt/bigdata/kafka_2.11-2.2.0/bin//kafka-server-start.sh -daemon /opt/
2021-06-01 10:53:02 510 1
原创 KAFKA那些事-01-概述
消息队列的缘由kafka是一种消息队列。在说kafka之前,我们先来聊一下消息队列的出现缘由。两个服务之间想要进行数据通信,如果直接点对点传输,会在数据的可靠性、一致性等方面让人头疼,因此为了解耦,人们的常用做法是在中间加一层东西进行服务之间解耦,而这个东西,就是消息队列。分布式消息队列与KAFKA的诞生但作为一个单机版的消息队列应用,势必存在单点问题和性能问题,因此必然需要发展成为一个分布式应用。按照分布式的老三样AKF原则,在X轴(可靠性横向副本扩展),Y轴(业务切分),Z轴(数据分区)上
2021-06-01 10:44:47 218 2
原创 IO那些事15-RPC调用的组合方式
RPCRPC,远程服务调用,只是一种调用行为的名称,而进行连接的双方使用的协议是不受限定的,可以是自定义的某种协议(自定义消息头和消息体,自行对传输消息的格式进行约定),也可以是比较公知的例如http协议(但其本质,应该说HTTP协议也是一种比较公认的自定义协议),但这无非就是调用协议层面的事情,整体来说,都是一种RPC的表现,所谓的通信有无状态,完全是看协议的实现是如何约定的。HTTP协议消费端,可以使用第三方HTTP类库,也可以使用netty支持的http协议客户端形式进行调用。服务端,既可以
2021-04-21 15:38:42 166
原创 IO那些事14-RPC优化点
RPC的层次感作为RPC调用来说,更多的还需要考虑用户体验度,对于用户来说,就是面向接口调用。然而实际上一个RPC的端点,可能既需要作为consumer去调用远程的provider的服务,而自身也作为一个provider提供着一些服务,作为这个端点来说,它对外提供的服务,对它自身肯定是一些本地的方法调用。所以我们在设计RPC通信时,调用的时候,不单单需要考虑只有远程调用,而应该首先去判断一下这个服务的实现方法在本地有没有,如果有的话,没必要再走RPC最终再调到自己身上来。 public stati
2021-04-21 15:36:32 265
原创 IO那些事13-IO的思考
多个ServerBootstrap可以实现一套计算资源,不同的处理逻辑IO密集型和计算密集型IO密集型就是和kernel打交道很多,会有比较多的系统调用。计算密集型则相反,更多的是在单纯用CPU做计算,而不怎么与内核打交道。正常来说,网卡到程序的过程中一定伴随着中断操作的干预,而当网卡数据来临非常频繁时,底层会进行优化,内核会关闭中断,然后直接让CPU疯狂从网卡的buffer中取出数据到内核的buffer中,且这个过程是底层系统硬件实现的。 但即使是这样,如果我们程序不尽快取走内核buffer中的数
2021-04-21 15:33:52 116 2
原创 IO那些事12-手写实现RPC
RPC调用整体图作为一段RPC调用模型来说,一般是分为consumer端和provider端,consumer端只需要面向接口编程,consumer端直接拿着接口, 然后直接调用其方法。而其内部,实质是通过socket通信(可以是netty也可以是其他),然后去请求provider端的具体接口实现类对应的方法。对于consumer端来说,可能多个不同的请求都是复用着一个channel连接,那这时候因此需要consumer端发起请求的时候需要带上各自的请求id,方便响应回来的时候,能够匹配是谁发出的请
2021-03-11 15:45:49 411
原创 IO那些事11-初识netty
引入依赖<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.43.Final</version></dependency>Netty中的ByteBufnetty对JDK原生nio中的ByteBuffer的包装。声明方式1、ByteBuf buf =
2021-03-01 15:14:51 193
原创 IO那些事10-手写简易版Reactor-IO实现
主线程代码实现:public class MainThread { public static void main(String[] args) { SelectorThreadGroup boss = new SelectorThreadGroup(1); SelectorThreadGroup worker = new SelectorThreadGroup(3); boss.setWorkerGroup(worker); bos
2021-03-01 15:09:37 287
原创 IO那些事09-JAVA API层面的IO历程02
import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;impor
2021-01-12 15:34:34 138
原创 IO那些事08-JAVA API层面的IO历程01
selector前面大篇幅的描述了IO的发展史,并谈到了多路复用的级别模型IO,当描述的这一切,都只是内核级别的调用,或者说是C级别的调用,而作为一个java程序员来说,更多的应该是API层面的使用。作为java api来说,无论是哪种模型,都统一抽象成了selector。来看一段java代码来了解:import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import jav
2021-01-12 15:19:24 176
原创 IO那些事07-多路复用IO之select,poll,epoll
多路复用器下的实现所有的多路复用器都是基于POSIX的规范进行实现的。SELECT最通用的多路复用器,也就是基本所有操作系统都有的,就是selectman 2 selectselect的参数可以发现是传入若干个文件描述符(读的和写的),但是一次调用可以操作的文件描述符FD_SETSIZE最大不能超过1024个。nfds:操作多少个文件描述符readfds:读的文件描述符集合writefds:写的文件描述符集合timeout:等待的时间,超过时间后,直接返回当前的文件描述符的状态。.
2021-01-04 11:17:25 207
原创 IO那些事06-网络IO之IO角度下的NIO
NIO的语义在java中,NIO意思是New IO在操作系统中,NIO意思是非阻塞IO代码实例import java.net.InetSocketAddress;import java.net.StandardSocketOptions;import java.nio.ByteBuffer;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.util.
2020-12-21 10:55:45 131
原创 IO那些事05-网络IO之IO角度下的BIO
/** * BIO 多线程的方式 */public class SocketIOPropertites { //server socket listen property: private static final int RECEIVE_BUFFER = 10; private static final int SO_TIMEOUT = 0; private static final boolean REUSE_ADDR = false; //当线程不够
2020-12-21 10:53:30 174
原创 IO那些事04-网络IO之TCP
传统的BIO模型下的,服务端代码:/** * BIO 多线程的方式 */public class SocketIOPropertites { //server socket listen property: private static final int RECEIVE_BUFFER = 10; private static final int SO_TIMEOUT = 0; private static final boolean REUSE_ADDR =
2020-12-21 10:48:22 249
原创 IO那些事03-几种常见的文件IO模型
java中的普通write和buffer read的重要差距?每次写数据data:“123456789\n”通过查看追踪系统调用线程文件,发现普通write,每一次write,实质都是一次系统调用,也就是都会发生一次内核态切换:通过查看追踪系统调用线程文件,发现buffered的write,每一次write,写的是一个缓冲区的若干个“123456789\n”:NIO在jdk新版,除了传统IO,又出现了新的IO,也就是NIO,也暴露了新的API,ByteBuffer public voi
2020-11-30 15:28:01 382
原创 IO那些事02-PageCache
PageCache为了提升IO的效率,计算机的整体各处都是存在页缓存的概念的。作为应用进程来说,一般都会存在以4k为单位的缓存页,也就是buffer,可以想象java中的bufferreader等。。接着,作为系统内核来说,它内部也存在页缓存(pagecache)。最后,对于硬盘的驱动本身,也存在缓冲区。因此可以想象,读取一份文件,会从磁盘驱动本身开始,每次读到缓冲区大小的内容才会向上级返回,这样大大提高IO的效率。而除了多级缓存之外,我们也不难想到,IO是个很慢的操作,如果一直让CPU去频
2020-11-30 15:20:42 334
原创 IO那些事01-IO总述和文件描述符
VFS内核既管内存,又管磁盘IO。作为LINUX内核来说,它在内存中构建了一个虚拟文件系统VFS,不同于windows上的物理文件系统结构,C盘代表的就是物理的C盘分区,D盘就是D盘的物理分区,VFS本质就是一颗目录树,每个目录可以映射代表不同的物理设备。为什么要有VFS?因为VFS相当于一个中间的解耦层,下层的存储源的存储形式可能是各不相同的,可能是来自不同的硬件设备,但需要将这些包成一个统一的对外接口暴露给上层应用使用。pagecache在VFS中,每一个文件都有一个inode id作为.
2020-11-30 15:17:59 1794
原创 JAVA程序员需要知道的计算机底层基础10-操作系统引导程序的简单制作
汇编实现引导程序编写汇编码; 文件名 boot.asm org 7c00h ; BIOS读入MBR(Master Boot Record主引导记录)后,从0x7c00h处开始执行,所以这里把程序扔到内存的0x7c00h中去 ; 下面部分和10h有关中断,10h中断用来显示字符mov ax, csmov es, axmov ax, msgmov bp, ax ; ES:BP表示显示字符串的地址mov cx, msgLen
2020-10-25 21:56:24 377 1
原创 JAVA程序员需要知道的计算机底层基础09-内核同步机制
关于同步理论的一些基本概念临界区(critical area)访问或操作共享数据的代码段。简单理解:synchronized大括号中部分(原子性)竞争条件(race conditions)两个线程同时拥有临界区的执行权数据不一致(data unconsistency)由竞争条件引起的数据破坏同步(synchronization)避免race conditions锁完成同步的手段(门锁,门后是临界区,只允许一个线程存在)这意味着上锁解锁的操作必须具备原子性。底层lock指令支持原
2020-10-25 21:52:13 293 4
原创 JAVA程序员需要知道的计算机底层基础08-内存管理的发展历程与现代内存管理机制
DOS时代在DOS时代 ,内存很小,同一时间只能有一个进程在运行(也有一些特殊算法可以支持多进程,通过栈来手动实现多进程之间的切换,但这个比较特殊很少见,不做讨论)Winwods9X时代内存变大,可以让多个进程装入内存。但依然存在问题:1、内存不够用,多个进程同时装入,但内存时有限的。2、互相打扰,因为多个进程同时存在于内存中,那意味着某一个进程可以随意去访问另外一个进程的物理内存地址,这也是非常危险的一件事情,恶意攻击将变得非常容易。为了解决这两个问题,诞生了现在的内存管理系统:虚拟地址 分
2020-10-25 21:49:46 273
原创 JAVA程序员需要知道的计算机底层基础07-中断
中断是和操作系统内核通信的一种机制,它本身也是一种信号,举个例子,一个应用程序运行过程中出现了卡顿,此时CPU在全力执行这个程序的进程,我们想通过键盘或者鼠标的某个按键来告诉操作系统将这个进程进行关闭(也就是想通过硬件的操作来让软件有个反馈),此时就需要用到中断,也就是说发送了一个紧急信号,希望内核命令应用程序可以停下手头的工作,然后优先进行处理我的某个操作。中断分为硬中断和软中断,我们上面描述的例子,其实就是硬中断的一个过程。硬中断1、键盘按下了一个键。2、中断控制器(一个芯片)收到了来自键盘.
2020-10-25 21:46:15 383
原创 JAVA程序员需要知道的计算机底层基础06-进程调度
一个操作系统往往是存在很多进程的,虽然内存是各自独立的,但CPU确是共享,那势必存在一个多个进程之间调度执行的问题,也就是什么时候执行这个进程,什么时候执行另外一个进程的,各自执行多久?这种问题。linux中的调度方式非常灵活,不是像其他有些操作系统一样固定只有一种的,而是可以根据对应的调度策略进行调度,而调度策略可以由开发内核的进行自定义策略编写,当然linux自身也已经提供了一些调度策略,一般来说我们不需要手动去编写(能编写那你也得会写内核)。进程调度发展历程早期的dos系统只支持单任务运行,.
2020-09-28 14:16:09 226
原创 JAVA程序员需要知道的计算机底层基础05-进程、线程、纤程(协程)
每一个程序都可以启动多个进程。而每一个进程中会有若干个线程。进程和线程有什么区别?简单说:进程就是一个程序运行起来的状态,线程是一个进程中的不同的执行路径。专业一点:进程是OS分配资源的基本单位,线程是执行调度的基本单位。分配资源最重要的是:会为每一个进程分配独立的内存地址空间。当进程被启动时,内存中会有一个main主线程启动,而其中可能会有多个线程,一旦程序执行时当CPU发生计算时,此时会由内存中某一个线程调度执行,因此说是线程是执行调度的基本单元。一个进程内的所有线程共享进程的内存空间.
2020-09-28 14:10:44 252
原创 JAVA程序员需要知道的计算机底层基础04-操作系统
操作系统其实也是一个软件,既管理着硬件,又开放一些软件接口提供给用户。操作系统基本分为内核kernel和外围, 内核主要和硬件打交道,外围就是和用户打交道。内核的分类宏内核就是将所有的功能都放在一块内存空间中,想要哪块功能就直接在内部找就行。使用对象:PC phone微内核内核主要只负责进程调度一块,其他每一块都是分开的, 当请求某一块功能时如果没有,内核会通过定位寻找(可能通过网络)来找到对应的位置。微服务的设计理念,万物互联。 好处:可插拔,弹性部署。 缺点:相比宏内核,...
2020-09-18 15:44:43 369
空空如也
这是一段植物大战僵尸的代码,但存在错误,第一发子弹会在第二发子弹发射后停止调用函数,求解
2017-04-16
本人js初学者、如何用js通过循环求一个数的位数
2017-03-21
本人js初学者、如何用js通过循环求一个数的位数
2017-03-21
本人js初学者、有一道题需要求助。求帮助
2017-03-17
本人js初学者、有一道题需要求助。求帮助
2017-03-17
本人JS初学者,1到100之间偶数的和,在JS框架里实现
2016-12-24
本人js初学者,求教如何在js中通过函数调用改变超链接颜色
2016-12-23
本人JS初学者,看到一道题。
2016-12-23
TA创建的收藏夹 TA关注的收藏夹
TA关注的人