0%

分布式锁和分布式限流器应该是算是比较常见的需求了,而Redis现在几乎是应用的标配了,于是很多人会倾向于选择基于Redis来实现,因为不需要引入额外的依赖。

分布式锁和分布式限流器在Java领域比较成熟和常用的开源实现是Redisson(中文官方介绍),下面从它的极小部分源码,分析下分布式锁和分布式限流器的实现逻辑。

Spark内存模型

Spark之所以快,很大程度上是因为它善于利用内存,大量利用内存进行存储和计算,从而减少磁盘IO,提升执行效率。

从1.6版本开始,Spark引入了统一内存管理模型(之前版本只有静态内存管理,这里不细说),找到两张图描述的很清楚:

spark-mem-on-heap.png

spark-mem-off-heap.png

为什么有两张图呢,因为Spark既能使用JVM堆内存(on-heap),也能使用堆外内存(off-heap),两张图分别描述的是这两块内存的情况。图中已经把Spark对内存容量的划分很形象的说明了,网上相关文章也不少,不再赘述。

Overview

所谓shuffle就是将数据按新的规则进行分区的过程,将数据分区从旧分区转变成新分区。

20191229115009.png

这个过程分为两个阶段,第一个阶段称为shuffle write,每个计算节点需要对自己持有的那部分数据按新分区规则进行重新分区,并按新分区写入文件。
shuffle write完成后,同一个新分区的数据会分散在不同的节点上,这样是不利于接下来的计算的,必须把同一个新分区的数据汇集到一个节点才行,所以需要第二阶段shuffle read。
shuffle read阶段将按照新分区,拉取shuffle write生成的文件,相同新分区的数据汇集到同一节点,组合成新的分区,这样才算是实现了新的数据分区。

Overview

调度系统,是贯穿整个Spark应用的主心骨,从调度系统开始入手了解Spark Core,比较容易理清头绪。

Spark的资源调度采用的是常见的两层调度,底层资源的管理和分配是第一层调度,交给YARN、Mesos或者Spark的Standalone集群处理,Application从第一层调度拿到资源后,还要进行内部的任务和资源调度,将任务和资源进行匹配,这是第二层调度,本文讲的就是这第二层调度

引言

Spark Core是Spark的核心部分,是Spark SQL,Spark Streaming,Spark MLlib等等其他模块的基础, Spark Core提供了开发分布式应用的脚手架,使得其他模块或应用的开发者不必关心复杂的分布式计算如何实现,只需使用Spark Core提供的分布式数据结构RDD及丰富的算子API,以类似开发单机应用的方式来进行开发。

这篇短文将结合实例对隐式转换的各种场景进行解释和总结,希望看完的人能够安全驶过隐式转换这个大坑。

隐式转换函数

隐式转换函数有两种作用场景。

  • 1 转换为期望类型:就是指一旦编译器看到X,但需要Y,就会检查从X到Y的隐式转换函数。
  • 2 转换方法的调用者:简单来说,如obj.f(),如果obj对象没有f方法,则尝试将obj转换为拥有f方法的类型。

创建线程是一个重量级操作,因为需要调用操作系统内核的API,所以最好不要频繁的创建和销毁线程,为了能够复用创建的线程,常用的办法的就是创建线程池。

Executor

java.util.concurren包中提供了若干接口和类来实现线程池,最常用的有Executor,ExecutorService,ThreadPoolExecutor。

Semaphore信号量模型,是一种通过维护计数器数值来控制并发数量的模型,Lock实现的互斥锁只允许一个线程访问临界区,而Semaphore允许有限多个线程访问临界区。

什么情况需要允许多个线程同时访问?最常见的需求就是池化资源,连接池、线程池、对象池等等。

java.util.concurren.Semaphore 是JDK中的实现类,常用方法有这些:

Scala并发编程实战:Lock 锁中我们了解到如何通过Lock来实现互斥操作,但是获取锁之后,如果发现条件不满足(如消费一个队列中的数据时,发现队列为空),线程要如何等待条件满足(如队列不为空)并让出锁呢?这需要用到Condition条件变量,又称作条件队列。

Condition与JDK内置的管程的等待队列功能类似,主要功能都是让线程在队列上等待被唤醒,但是内置管程的锁只能有一个对应的队列,而一个Lock锁可以有多个Condition队列。

synchronized作为内置锁,使用简单,不易出错,然鹅确有相当的局限性,例如,无法从等待获取锁的阻塞中中断,无法设置获取锁的超时。
所以JUC提供了另一种更灵活的加锁方式,即Lock。

Lock

Lock接口定义如下

public interface Lock {
void lock();
void lockInterruptibly() throws InterruptedException;
boolean tryLock();
boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException;
void unlock();
Condition newCondition();
}