Flink知识点
1. Flink、Storm、Sparkstreaming对比
storm------ ---------At-least-once----Record Acks-------无状态管理-------- 低延迟-----------高吞吐sparkstreaming-----Exactly-once-------RDD Checkpoint-----基于DStream-----中等延迟-----高吞吐Flink-----------------Exactly-once------ Checkpoint-----------基于操作----------低延迟-------高吞吐
2. Flink DataStream API基本算子
3. Flink On Yarn
- 提高集群机器的利用率;
- 一套集群,可以同时执行MR任务,Spark任务,Flink任务。
- 一开始在Yarn上初始化一个集群;yarn-session.sh【开辟资源】+flink run【提交任务】
- 每个Flink job都申请一个集群,互不影响,任务执行之后资源会被释放掉。flink run -m yarn-cluster【开辟资源+提交任务】
4. FlinkKafkaConnector(FlinkKafkaConsumer+FlinkKafkaProducer)
阅读过FlinkKafkaConnector源码后对Kafka偏移量的存储机制有了一个全新的认识,这里有两个坑,简单记下:
- FlinkKafkaComsumer08用的Kafka老版本Consumer,偏移量提交Zookeeper,由Zookeeper保管,而FlinkKafkaComsumer09以后,偏移量默认存在Kafka内部的Topic中,不再向Zookeeper提交;
- 使用FlinkKafkaProducer08写Kafka1.10(其他高版本没试过)存在超时。
5. DataStream API之partition
- 随机分区
dataStream.shuffle();
- 重分区,消除数据倾斜
dataStream.rebalance();
- 自定义分区
dataStream.partitionCustom(partiitoner,"somekey");
- 广播分区:把元素广播所有分区,会被重复消费
DataStream.broadcast();
6. Flink Distributed Cache(分布式缓存)
- 原理
- 用法
用法一:注册一个文件
env.registerCachedFile(“hdfs:///path/to/yout/file","hdfsfile");
用法二:访问数据
File myFile = getRuntimeContext().getDistributedCache().getFile("hdfsFile");
7. State
8. Checkpoint
env.enableCheckpointing(1000); //每隔1000ms设置一个检查点【检查点周期】
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);//设置模式为exactly once(默认值)
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);//检查点之间至少有500ms的间隔【检查点最小间隔】
env.getCheckpointConfig().setCheckpointTimeout(60000); //检查点必须在一分钟之内完成,否则丢弃【检查点的超时时间】
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1); //同一时间点只允许一个检查点
6 env.getCheckpointConfig().enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION);
7 //Flink程序被取消后,会保留检查点数据
9. Flink重启策略
10. Window(窗口)
- 滚动窗口【没有重叠】tumbling windows
.timeWindow(Time.minutes(1));
.countWindow(100);
- 滑动窗口【有重叠】sliding windows
.timeWindow(Time.minutes(1),Time.seconds(30))//每隔30秒,统计一分钟的数据
.countWindow(100,10)//每隔10条数据,统计100条的数据
- 会话窗口 session windows
- 增量聚合(窗口中每进入一条数据,就进行一次计算),例如reduce、aggregate、sum、min、max;
- 全量聚合(等窗口所有数据到齐,才开始计算,可以进行排序等)例如apply、process等
当然也可以分为keyed window和non-keyed window,分组的stream调用keyBy(...)和window(...),非分组的stream中window(...)换成了windowAll(...)
11. Time
- Event Time:日志产生的时间;
- Ingestion Time:事件从kafka等取出来,进入Flink的时间;
- Processing Time:事件被处理的时间,例如达到窗口处理的时间等。【默认】
12. Flink并行度
- Flink中每个TaskManager为集群提供slot,slot数量与每个节点的可用CPU核数成比例,slot上启动进程,进程内有多个线程。如果任务管理器有n个槽,它会为每个槽分配 1/n 的内存,这里没有对 CPU 进行隔离;目前任务槽仅仅用于划分任务的内存。
配置一个TaskManager有多少个并发的slot数有两种配置方式:
- taskmanager.numberOfTaskSlots。在conf/flink-conf.yaml中更改,默认值为1,表示默认一个TaskManager只有1个task slot.
- 提交作业时通过参数配置。--yarnslots 1,表示TaskManager的slot数为1.
⚠️注意:slot不能搞太多,几十个就行,你想啊假如你机器不多,TaskManager不多,搞那么多slot,每个slot分到的内存小的可怜,容易OOM啊
- 并行度的设置有多个地方:操作算子层面、执行环境层面、客户端层面、系统层面,具体可以参考:FLINK并行度;
val wordCounts = text
.flatMap{ _.split(" ") map { (_, 1) } }
.keyBy(0)
.timeWindow(Time.seconds(5))
.sum(1).setParallelism(5)
执行环境层面比如:
env.setParallelism(5)
提交任务的时候,在客户端侧flink可以通过-p参数来设置并行度。例如:
./bin/flink run -p 5 ../examples/*WordCount-java*.jar
13. TaskManager数量
14. Flink传递参数给函数
使用构造函数方式
DataSet toFilter = env.fromElements(1, 2, 3);
toFilter.filter(new MyFilter(2));
private static class MyFilter implements FilterFunction {
private final int limit;
public MyFilter(int limit) {
this.limit = limit;
}
@Override
public boolean filter(Integer value) throws Exception {
return value > limit;
}
}
DataSet toFilter = env.fromElements(1, 2, 3);
Configuration config = new Configuration();
config.setInteger("limit", 2);
toFilter.filter(new RichFilterFunction() {
private int limit;
@Override
public void open(Configuration parameters) throws Exception {
limit = parameters.getInteger("limit", 0);
}
@Override
public boolean filter(Integer value) throws Exception {
return value > limit;
}
}).withParameters(config);
Configuration conf = new Configuration();
conf.setString("mykey","myvalue");
final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
env.getConfig().setGlobalJobParameters(conf);
public static final class Tokenizer extends RichFlatMapFunction> {
private String mykey;
@Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
ExecutionConfig.GlobalJobParameters globalParams = getRuntimeContext().getExecutionConfig().getGlobalJobParameters();
Configuration globConf = (Configuration) globalParams;
mykey = globConf.getString("mykey", null);
}
// ... more here ...
15. Flink中的Metrics
import org.apache.flink.api.common.accumulators.LongCounter;
import org.apache.flink.api.common.functions.RichMapFunction;
import org.apache.flink.api.java.utils.ParameterTool;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.dropwizard.metrics.DropwizardMeterWrapper;
import org.apache.flink.metrics.Counter;
import org.apache.flink.metrics.Meter;
import org.apache.flink.metrics.MetricGroup; public class Map extends RichMapFunction<String, String> {
private transient Meter logTotalMeter;
private transient Counter logTotalConter;
private LongCounter logAcc = new LongCounter(); @Override
public void open(Configuration parameters) throws Exception {
MetricGroup metricGroup = getRuntimeContext().getMetricGroup();
logTotalMeter = metricGroup.meter("logTotalMeter",
new DropwizardMeterWrapper(new com.codahale.metrics.Meter()));
logTotalConter = metricGroup.counter("logTotalConter");
getRuntimeContext().addAccumulator("logAcc", this.logAcc);
} @Override
public String map(String log) throws Exception {
logTotalConter.inc();
logTotalMeter.markEvent();
logAcc.add(NumberUtil.LONG_ONE);
logMeter.mark();
return log;
}
}
16. Flink中的table API
声明式-用户只关心做什么,不用关心怎么做;高性能-支持查询优化,可以获取更好的执行性能;流批统一-相同的统计逻辑,既可以流模式也可以批模式;标准稳定-语义遵循SQL标准,不易变动易理解-所见即所得
// table API
tab.groupBy("word").select("word,count(1) as cnt") // SQL
SELECT COUNT(1) AS cnt
FROM tab
GROUP BY word
总的来说,SQL有的功能table API都有,如下图所示
三种注册表的方式
三种发射表的方式
table API对列操作比较方便,比如
再比如有一张100列的表,选择1到10列怎么操作?
另外,table API的map函数扩展起来也很方便
也可参考:Table API & SQL、Flink SQL-Client。
17. Flink中的内存管理
./bin/flink run -m yarn-cluster -yn 2 -yjm 1024 -ytm 1024 ./examples/batch/WordCount.jar
红色参数的具体含义是(参见Flink官网):
-yjm,--yarnjobManagerMemory <arg> Memory for JobManager Container
with optional unit (default: MB)
-ytm,--yarntaskManagerMemory <arg> Memory per TaskManager Container
with optional unit (default: MB)
先上两个小图(这俩图我没找到原版出处,一直觉得这玩意坑爹,大概率上这里的JVM Heap包括了on-heap和off-heap,on-heap和off-heap下边有介绍)
看图说话,TaskManager 的堆内存主要被分成了三个部分:
- Network Buffers: 一定数量的32KB大小的 buffer,主要用于数据的网络传输。在 TaskManager 启动的时候就会分配。默认数量是 2048 个,可以通过
taskmanager.network.numberOfBuffers
来配置。 - Memory Manager Pool: 这是一个由
MemoryManager
管理的,由众多MemorySegment
组成的超大集合。Flink 中的算法(如 sort/shuffle/join)会向这个内存池申请 MemorySegment,将序列化后的数据存于其中,使用完后释放回内存池。默认情况下,池子占了堆内存的 70% 的大小。 - Remaining (Free) Heap: 这部分的内存是留给用户代码以及 TaskManager 的数据结构使用的。因为这些数据结构一般都很小,所以基本上这些内存都是给用户代码使用的。从GC的角度来看,可以把这里看成的新生代,也就是说这里主要都是由用户代码生成的短期对象。
⚠️注意:Memory Manager Pool 主要在Batch模式下使用。在Steaming模式下,该池子不会预分配内存,也不会向该池子请求内存块。也就是说该部分的内存都是可以给用户代码使用的。不过社区是打算在 Streaming 模式下也能将该池子利用起来。
从堆的角度来说,Flink当前的内存支持堆内(on-heap)和堆外(off-heap)管理,用户想去申请什么类型的内存,有相关的参数去配置。Flink off-heap的内存管理相对于on-heap的优点主要在于:
- 启动分配了大内存(例如100G)的JVM很耗费时间,垃圾回收也很慢。如果采用off-heap,剩下的Network buffer和Remaining heap都会很小,垃圾回收也不用考虑MemorySegment中的Java对象了,节省了GC时间;
- 有效防止OOM,MemorySegment大小固定,操作高效。如果MemorySegment不足写到磁盘,内存中的数据不多,一般不会发生OOM;
- 更有效率的IO操作。在off-heap下,将MemorySegment写到磁盘或是网络可以支持zeor-copy技术,而on-heap的话则至少需要一次内存拷贝;
- off-heap上的数据可以和其他程序共享。
好了概念讲了一通,看下任务TaskManager日志
2019-07-23 07:27:50,035 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - Starting YARN TaskExecutor runner (Version: 1.7.1, Rev:<unknown>, Date:<unknown>)
2019-07-23 07:27:50,035 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - OS current user: yarn
2019-07-23 07:27:50,436 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - Current Hadoop/Kerberos user: worker
2019-07-23 07:27:50,436 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - JVM: Java HotSpot(TM) 64-Bit Server VM - Oracle Corporation - 1.8/25.112-b15
2019-07-23 07:27:50,436 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - Maximum heap size: MiBytes
2019-07-23 07:27:50,437 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - JAVA_HOME: /usr/local/jdk/
2019-07-23 07:27:50,438 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - Hadoop version: 2.6.0-cdh5.5.0
2019-07-23 07:27:50,438 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - JVM Options:
2019-07-23 07:27:50,438 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - -Xmsm
2019-07-23 07:27:50,439 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - -Xmxm
2019-07-23 07:27:50,439 INFO org.apache.flink.yarn.YarnTaskExecutorRunner - -XX:MaxDirectMemorySize=m
红色的地方有几个值,Flink源码中这几个值的计算在TaskManagerServices.calculateHeapSizeMB(计算堆内内存大小)和calculateNetworkBufferMemory(计算堆外内存大小),下边我们来看默认情况下这些值怎么计算的(仅限Flink 1.7.1版本,其他版本系数可能有变化)。
1. JVM预留内存,总内存的25%,最小预留,600M:
1024MB - (1024 * 0.25 < 600MB) -> 600MB = 424MB (cutoff)
2. 剩下的内存的10%作为networkBuffer的内存,最小64M:
424MB - (424MB * 0.1 < 64MB) -> 64MB(networkbuffer) = MB
3. 批作业的话剩下内存30%设为堆内内存,总内存减去堆内内存设为directMemory,流作业全部都是堆内内存了,用于netty和rocksDB和networkBuffer以及JVM自身内存。
这样360M和664M都明了了,那为啥一开始日志打印“Maximum heap size: 345 MiBytes”呢,这里还有一个小坑,先看Flink怎么计算的,
/**
* The maximum JVM heap size, in bytes.
*
* <p>This method uses the <i>-Xmx</i> value of the JVM, if set. If not set, it returns (as
* a heuristic) 1/4th of the physical memory size.
*
* @return The maximum JVM heap size, in bytes.
*/
public static long getMaxJvmHeapMemory() {
final long maxMemory = Runtime.getRuntime().maxMemory();
if (maxMemory != Long.MAX_VALUE) {
// we have the proper max memory
return maxMemory;
} else {
// max JVM heap size is not set - use the heuristic to use 1/4th of the physical memory
final long physicalMemory = Hardware.getSizeOfPhysicalMemory();
if (physicalMemory != -1) {
// got proper value for physical memory
return physicalMemory / 4;
} else {
throw new RuntimeException("Could not determine the amount of free memory.\n" +
"Please set the maximum memory for the JVM, e.g. -Xmx512M for 512 megabytes.");
}
}
}
它用了Java lang的方法,这就有问题了,问题在于JVM使用的GC算法都会有一些内存丢失,比如Survivor有两个,但只有1个会用到,另一个一直闲置,总有一块Survivor区是不被计算到可用内存中的。
到底是不是呢,我在Flink程序的Map函数中加了这么一段代码:
logger.info("Runtime max: " + mb(Runtime.getRuntime().maxMemory()));
MemoryMXBean m = ManagementFactory.getMemoryMXBean(); logger.info("Non-heap: " + mb(m.getNonHeapMemoryUsage().getMax()));
logger.info("Heap: " + mb(m.getHeapMemoryUsage().getMax())); for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) {
logger.info("Pool: " + mp.getName() + " (type " + mp.getType() + ")" + " = " + mb(mp.getUsage().getMax()));
}
打印日志出来
2019-07-20 09:03:16,344 INFO data.demo.core.example - Heap: 361758720 (345.00 M)
2019-07-20 09:03:16,344 INFO data.demo.core.example - Pool: PS Survivor Space (type Heap memory) = 15728640 (15.00 M)
2019-07-20 09:03:16,344 INFO data.demo.core.example - Pool: Code Cache (type Non-heap memory) = 251658240 (240.00 M)
2019-07-20 09:03:16,344 INFO data.demo.core.example - Pool: PS Old Gen (type Heap memory) = 251658240 (240.00 M)
2019-07-20 09:03:16,344 INFO data.demo.core.example - Pool: Metaspace (type Non-heap memory) = -1 (-0.00 M)
2019-07-20 09:03:16,344 INFO data.demo.core.example - Pool: Compressed Class Space (type Non-heap memory) = 1073741824 (1024.00 M)
2019-07-20 09:03:16,344 INFO data.demo.core.example - Pool: PS Eden Space (type Heap memory) = 94371840 (90.00 M)
2019-07-20 09:03:16,344 INFO data.demo.core.example - Pool: PS Survivor Space (type Heap memory) = (15.00 M)
2019-07-20 09:03:16,345 INFO data.demo.core.example - Pool: PS Old Gen (type Heap memory) = 251658240 (240.00 M)
2019-07-20 09:03:16,345 INFO data.demo.core.example - Runtime max: 361758720 (345.00 M)
眼见为实,实锤了。
再看Flink TaskManager WebUI
有一些概念还要说下,比如JVM管理两种类型的内存:堆(heap)和非堆(Nonheap),堆就是Java代码可及的内存,所有类实例和数组的内存都是在堆上分配。非堆就是JVM留给自己用的,方法区、栈、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法的代码都在非堆内存中。
再比如Direct和Mapped,这俩是JVM缓冲池,主要是JNI使用。
UI上的这些参数我们都可以通过Flink的Rest API拿到下面这些指标值,比如通过访问本地localhost:23799/taskmanagers/container_e37_1563420494990_0370_01_000009(具体参见Flink官网):
Scope | Infix | Metrics | Description |
---|---|---|---|
Job-/TaskManager | Status.JVM.Memory | Memory.Heap.Used | 当前使用的堆内存大小. |
Heap.Committed | 保证JVM可用的堆内存大小. | ||
Heap.Max | 可用于内存管理的堆内存最大值. | ||
NonHeap.Used | 当前使用的非堆内存大小. | ||
NonHeap.Committed | 保证JVM可用的非堆内存大小. | ||
NonHeap.Max | 可用于内存管理的非堆内存最大值. | ||
Direct.Count | 直接缓冲池中的缓冲区数量. | ||
Direct.MemoryUsed | JVM中用于直接缓冲池的内存大小. | ||
Direct.TotalCapacity | 直接缓冲池中所有缓冲区的总容量. | ||
Mapped.Count | 映射缓冲池中缓冲区的数量. | ||
Mapped.MemoryUsed | JVM中用于映射缓冲池的内存大小. | ||
Mapped.TotalCapacity | 映射缓冲池中缓冲区的数量. |
18. Flink中依赖配置
- Flink核心依赖:Flink本身由运行系统所需的一组类和依赖项组成,例如协调,网络,检查点,故障转移,API,操作(如窗口),资源管理等。所有这些这些类和依赖项构成了Flink运行时的核心,在启动Flink应用程序时必须存在。这些核心类和依赖项打包在flink-dist.jar中。它们是Flink lib文件夹的一部分。这部分不包含任何连接器或库(CEP,SQL,ML等),以避免默认情况下在类路径中具有过多的依赖项和类,保持默认的类路径较小并避免依赖性冲突。Maven(和其他构建工具)将依赖项打包时一般将核心依赖设为provided,如果它们未设置为provided,可能使生成的JAR包过大,还可能出现添加到应用程序的jar文件的Flink核心依赖项与用户自己的一些依赖版本冲突(可以通过反向类加载来避免);如果在IntelliJ IDEA中调试,则将scope设置为comiple,否则失败报
NoClassDefFountError错;
- 用户应用程序依赖: connectors, formats, or libraries(CEP, SQL, ML),用户应用程序通常打包到应用程序jar中。
另外,当Flink程序读写HDFS时需要添加Hadoop依赖,不要把Hadoop依赖直接添加到Flink application,而是: export HADOOP_CLASSPATH=`hadoop classpath`,Flink组件启动时会使用该环境变量,这样做是因为:
- 一些Hadoop交互发生在Flink的核心,可能在用户应用程序启动之前,例如为检查点设置HDFS,通过Hadoop的Kerberos令牌进行身份验证或在YARN上部署。
- Flink的反向类加载方法隐藏了核心依赖关系中的许多传递依赖关系,应用程序可以使用相同依赖项的不同版本,而不会遇到依赖项冲突。
19. Flink单元测试指南
20. Flink读HDFS
DataSet<String> hdfslines=env.readTextFile("your hdfs path")
写数据
hdfslines.writeAsText("your hdfs path")
以上会根据你的默认的线程数来生成多少个分区文件,如果你想最后生成一个文件的话,可以在后面使用setParallelism(1),这样最后就只会生成一个文件了。具体可以这么整
try {
String topic = args[0];
String path = args[1];
//读取配置文件
Configuration conf = new Configuration();
//获取文件系统
FileSystem fs = FileSystem.get(URI.create("/"), conf); System.out.println(fs.getUri());
if (!fs.getUri().toString().contains("hdfs")) {
path = "hdfs://localhost:8020" + path;
} ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
DataSet<String> union = env.readTextFile(fs.getUri() + path + "/").setParallelism(20); union.rebalance().setParallelism(15).map(new MapFunction<String, String>() {
private static final long serialVersionUID = 1033071381217373267L; @Override
public String map(String rawLog) throws Exception {
return rawLog;
}
}).output(new DiscardingOutputFormat<>())
.setParallelism(20);
try {
env.execute();
} catch (Exception e) {
e.printStackTrace();
} //关闭文件系统
fs.close();
} catch (Exception e) {
logger.error("task submit process error, due to {}.", e.getMessage());
e.printStackTrace();
}
path是传入的目录,比如/user/rawlog/hourly/2019-09-15/09
配置
21.
Flink知识点的更多相关文章
- 《大数据实时计算引擎 Flink 实战与性能优化》新专栏
基于 Flink 1.9 讲解的专栏,涉及入门.概念.原理.实战.性能调优.系统案例的讲解. 专栏介绍 扫码下面专栏二维码可以订阅该专栏 首发地址:http://www.54tianzhisheng. ...
- Flink神秘工具lib
Flink里面有一个神坑,叫做FI坑.其实只是使用Fi的时候被暴露出来.但是,杀不死你的,终将使你更加强大. Flink集群有一个lib文件件,里面比较happy,可以放各种jar:这样,client ...
- 为什么你学不会递归?告别递归,谈谈我的一些经验 关于集合中一些常考的知识点总结 .net辗转java系列(一)视野 彻底理解cookie,session,token
为什么你学不会递归?告别递归,谈谈我的一些经验 可能很多人在大一的时候,就已经接触了递归了,不过,我敢保证很多人初学者刚开始接触递归的时候,是一脸懵逼的,我当初也是,给我的感觉就是,递归太神奇了! ...
- flink相关
flink一.简单实时计算方案 假如现在我们有一个电商平台,每天访问的流量巨大,主要访问流量都集中在衣服类.家电类页面,那么我们想实时看到这两类页面的访问量走势(十分钟出一个统计量),当做平台的重要指 ...
- Flink初探wordCout
知识点 Flink介绍 1.无界数据-->数据不断产生 2.有界数据-->最终不再改变的数据 3.有界数据集是无界数据集的一个特例 4.有界数据集在flink内部是以一种终态数据集进行处理 ...
- 面试总结 | Linux后台开发不得不看的知识点(给进军bat的你!)
目录 一 自我介绍 二 面试情况 三 相关知识点汇总 1 c/c++相关 2 计算机网络 3 数据结构相关 4 数据库相关 5 操作系统 6 Linux基础知识及应用编程(后台必备!) 7 大数问题 ...
- 「Flink」Flink中的时间类型
Flink中的时间类型和窗口是非常重要概念,是学习Flink必须要掌握的两个知识点. Flink中的时间类型 时间类型介绍 Flink流式处理中支持不同类型的时间.分为以下几种: 处理时间 Flink ...
- Flink的DataSource三部曲之三:自定义
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Flink处理函数实战之一:深入了解ProcessFunction的状态(Flink-1.10)
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
随机推荐
- cf55D. Beautiful numbers(数位dp)
题意 题目链接 Sol 看到这种题就不难想到是数位dp了. 一个很显然的性质是一个数若能整除所有位数上的数,则一定能整除他们的lcm. 根据这个条件我们不难看出我们只需要记录每个数对所有数的lcm(也 ...
- Nginx 日志格式配置介绍
Nginx日志格式配置介绍 by:授客 QQ:1033553122 测试环境 CentOS 6.5-x86_64 nginx-1.10.0 配置例子 log_format main '$ ...
- Spring Data Redis 让 NoSQL 快如闪电(2)
[编者按]本文作者为 Xinyu Liu,文章的第一部分重点概述了 Redis 方方面面的特性.在第二部分,将介绍详细的用例.文章系国内 ITOM 管理平台 OneAPM 编译呈现. 把 Redis ...
- 智能POS打印配置&常见问题FAQ 12-14 后期持续更新
1.安卓一体机会员注销钱会不会退回到支付宝 智能pos会员注销钱目前只能现金退还. 2.支付异常订单悬浮球在哪关闭 设置-->功能设置-->系统设置-->开启支付异常订单悬浮球 3. ...
- MongoDB添加仲裁节点报错replica set IDs do not match办法
背景:由于历史原因,某个MongoDB副本集只有一主一从双节点,无法满足自动故障转移要求,需要配置一个仲裁节点. 原有节点192.168.10.20:27017,192.168.10.21:27017 ...
- Android内嵌PDF预览
一.在对应模块的build.gradle文件中加入依赖 dependencies { implementation 'com.github.barteksc:android-pdf-viewer:3. ...
- oracle- 数据表分区
1. 表分区概念 分区表是将大表的数据分成称为分区的许多小的子集.倘若硬盘丢失了分区表,数据就无法按顺序读取和写入,导致无法操作. 2. 表分区分类 (1)范围分区 create table tabl ...
- [Hive_add_1] Hive 与 MR 的对应关系
- Mybatis 报错 There is no getter for property named '***' in 'class java.lang.String'
在mapper.xml中 , 如果单参数是String类型 , 且在sql语句中对参数进行了判断 , 如下 when 中的判断 , 如果出现 if 判断也是一样的.都需要把判断中的参数用 _param ...
- K-means算法的matlab程序(初步)
K-means算法的matlab程序 在https://www.cnblogs.com/kailugaji/p/9648369.html 文章中已经介绍了K-means算法,现在用matlab程序实现 ...