Spark数据倾斜解决方案(转)

本文转发自技术世界,原文链接 http://www.jasongj.com/spark/skew/

Spark性能优化之道——解决Spark数据倾斜(Data Skew)的N种姿势

自定义Partitioner

原理

使用自定义的Partitioner(默认为HashPartitioner),将原本被分配到同一个Task的不同Key分配到不同Task。

案例

以上述数据集为例,继续将并发度设置为12,但是在groupByKey算子上,使用自定义的Partitioner(实现如下)

 1 .groupByKey(new Partitioner() {
 2 @Override
 3 public int numPartitions() {
 4 return 12;
 5 }
 6  
 7 @Override
 8 public int getPartition(Object key) {
 9 int id = Integer.parseInt(key.toString());
10 if(id >= 9500000 && id <= 9500084 && ((id - 9500000) % 12) == 0) {
11 return (id - 9500000) / 12;
12 } else {
13 return id % 12;
14 }
15 }
16 })

由下图可见,使用自定义Partition后,耗时最长的Task 6处理约1000万条数据,用时15秒。并且各Task所处理的数据集大小相当。 

customizec partitioner

总结

适用场景
大量不同的Key被分配到了相同的Task造成该Task数据量过大。

解决方案
使用自定义的Partitioner实现类代替默认的HashPartitioner,尽量将所有不同的Key均匀分配到不同的Task中。

优势
不影响原有的并行度设计。如果改变并行度,后续Stage的并行度也会默认改变,可能会影响后续Stage。

劣势
适用场景有限,只能将不同Key分散开,对于同一Key对应数据集非常大的场景不适用。效果与调整并行度类似,只能缓解数据倾斜而不能完全消除数据倾斜。而且需要根据数据特点自定义专用的Partitioner,不够灵活。

将Reduce side Join转变为Map side Join

原理

通过Spark的Broadcast机制,将Reduce侧Join转化为Map侧Join,避免Shuffle从而完全消除Shuffle带来的数据倾斜。
spark map join

案例

通过如下SQL创建一张具有倾斜Key且总记录数为1.5亿的大表test。

1 INSERT OVERWRITE TABLE test
2 SELECT CAST(CASE WHEN id < 980000000 THEN (95000000 + (CAST (RAND() * 4 AS INT) + 1) * 48 )
3 ELSE CAST(id/10 AS INT) END AS STRING),
4 name
5 FROM student_external
6 WHERE id BETWEEN 900000000 AND 1050000000;

使用如下SQL创建一张数据分布均匀且总记录数为50万的小表test_new。 

1 INSERT OVERWRITE TABLE test_new
2 SELECT CAST(CAST(id/10 AS INT) AS STRING),
3 name
4 FROM student_delta_external
5 WHERE id BETWEEN 950000000 AND 950500000;


直接通过Spark Thrift Server提交如下SQL将表test与表test_new进行Join并将Join结果存于表test_join中。
 

1 INSERT OVERWRITE TABLE test_join
2 SELECT test_new.id, test_new.name
3 FROM test
4 JOIN test_new
5 ON test.id = test_new.id;

该SQL对应的DAG如下图所示。从该图可见,该执行过程总共分为三个Stage,前两个用于从Hive中读取数据,同时二者进行Shuffle,通过最后一个Stage进行Join并将结果写入表test_join中。 

reduce join DAG

从下图可见,Join Stage各Task处理的数据倾斜严重,处理数据量最大的Task耗时7.1分钟,远高于其它无数据倾斜的Task约2秒的耗时。
reduce join DAG

接下来,尝试通过Broadcast实现Map侧Join。实现Map侧Join的方法,并非直接通过CACHE TABLE test_new将小表test_new进行cache。现通过如下SQL进行Join。

1 CACHE TABLE test_new;
2 INSERT OVERWRITE TABLE test_join
3 SELECT test_new.id, test_new.name
4 FROM test
5 JOIN test_new
6 ON test.id = test_new.id;


通过如下DAG图可见,该操作仍分为三个Stage,且仍然有Shuffle存在,唯一不同的是,小表的读取不再直接扫描Hive表,而是扫描内存中缓存的表。
 

reduce join DAG

并且数据倾斜仍然存在。如下图所示,最慢的Task耗时为7.1分钟,远高于其它Task的约2秒。
reduce join DAG

正确的使用Broadcast实现Map侧Join的方式是,通过SET spark.sql.autoBroadcastJoinThreshold=104857600;将Broadcast的阈值设置得足够大。

再次通过如下SQL进行Join。

1 SET spark.sql.autoBroadcastJoinThreshold=104857600;
2 INSERT OVERWRITE TABLE test_join
3 SELECT test_new.id, test_new.name
4 FROM test
5 JOIN test_new
6 ON test.id = test_new.id;

通过如下DAG图可见,该方案只包含一个Stage。 

reduce join DAG

并且从下图可见,各Task耗时相当,无明显数据倾斜现象。并且总耗时为1.5分钟,远低于Reduce侧Join的7.3分钟。
reduce join DAG

总结

适用场景
参与Join的一边数据集足够小,可被加载进Driver并通过Broadcast方法广播到各个Executor中。

解决方案
在Java/Scala代码中将小数据集数据拉取到Driver,然后通过Broadcast方案将小数据集的数据广播到各Executor。或者在使用SQL前,将Broadcast的阈值调整得足够大,从而使用Broadcast生效。进而将Reduce侧Join替换为Map侧Join。

优势
避免了Shuffle,彻底消除了数据倾斜产生的条件,可极大提升性能。

劣势
要求参与Join的一侧数据集足够小,并且主要适用于Join的场景,不适合聚合的场景,适用条件有限。

为skew的key增加随机前/后缀

原理

为数据量特别大的Key增加随机前/后缀,使得原来Key相同的数据变为Key不相同的数据,从而使倾斜的数据集分散到不同的Task中,彻底解决数据倾斜问题。Join另一则的数据中,与倾斜Key对应的部分数据,与随机前缀集作笛卡尔乘积,从而保证无论数据倾斜侧倾斜Key如何加前缀,都能与之正常Join。
spark random prefix

案例

通过如下SQL,将id为9亿到9.08亿共800万条数据的id转为9500048或者9500096,其它数据的id除以100取整。从而该数据集中,id为9500048和9500096的数据各400万,其它id对应的数据记录数均为100条。这些数据存于名为test的表中。

对于另外一张小表test_new,取出50万条数据,并将id(递增且唯一)除以100取整,使得所有id都对应100条数据。

 1 INSERT OVERWRITE TABLE test
 2 SELECT CAST(CASE WHEN id < 908000000 THEN (9500000 + (CAST (RAND() * 2 AS INT) + 1) * 48 )
 3 ELSE CAST(id/100 AS INT) END AS STRING),
 4 name
 5 FROM student_external
 6 WHERE id BETWEEN 900000000 AND 1050000000;
 7  
 8 INSERT OVERWRITE TABLE test_new
 9 SELECT CAST(CAST(id/100 AS INT) AS STRING),
10 name
11 FROM student_delta_external
12 WHERE id BETWEEN 950000000 AND 950500000;


 
通过如下代码,读取test表对应的文件夹内的数据并转换为JavaPairRDD存于leftRDD中,同样读取test表对应的数据存于rightRDD中。通过RDD的join算子对leftRDD与rightRDD进行Join,并指定并行度为48。

 1 public class SparkDataSkew{
 2 public static void main(String[] args) {
 3 SparkConf sparkConf = new SparkConf();
 4 sparkConf.setAppName("DemoSparkDataFrameWithSkewedBigTableDirect");
 5 sparkConf.set("spark.default.parallelism", String.valueOf(parallelism));
 6 JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);
 7  
 8 JavaPairRDD<String, String> leftRDD = javaSparkContext.textFile("hdfs://hadoop1:8020/apps/hive/warehouse/default/test/")
 9 .mapToPair((String row) -> {
10 String[] str = row.split(",");
11 return new Tuple2<String, String>(str[0], str[1]);
12 });
13  
14 JavaPairRDD<String, String> rightRDD = javaSparkContext.textFile("hdfs://hadoop1:8020/apps/hive/warehouse/default/test_new/")
15 .mapToPair((String row) -> {
16 String[] str = row.split(",");
17 return new Tuple2<String, String>(str[0], str[1]);
18 });
19  
20 leftRDD.join(rightRDD, parallelism)
21 .mapToPair((Tuple2<String, Tuple2<String, String>> tuple) -> new Tuple2<String, String>(tuple._1(), tuple._2()._2()))
22 .foreachPartition((Iterator<Tuple2<String, String>> iterator) -> {
23 AtomicInteger atomicInteger = new AtomicInteger();
24 iterator.forEachRemaining((Tuple2<String, String> tuple) -> atomicInteger.incrementAndGet());
25 });
26  
27 javaSparkContext.stop();
28 javaSparkContext.close();
29 }
30 }

从下图可看出,整个Join耗时1分54秒,其中Join Stage耗时1.7分钟。
few skewed key join

通过分析Join Stage的所有Task可知,在其它Task所处理记录数为192.71万的同时Task 32的处理的记录数为992.72万,故它耗时为1.7分钟,远高于其它Task的约10秒。这与上文准备数据集时,将id为9500048为9500096对应的数据量设置非常大,其它id对应的数据集非常均匀相符合。
few skewed key join

现通过如下操作,实现倾斜Key的分散处理

  • 将leftRDD中倾斜的key(即9500048与9500096)对应的数据单独过滤出来,且加上1到24的随机前缀,并将前缀与原数据用逗号分隔(以方便之后去掉前缀)形成单独的leftSkewRDD
  • 将rightRDD中倾斜key对应的数据抽取出来,并通过flatMap操作将该数据集中每条数据均转换为24条数据(每条分别加上1到24的随机前缀),形成单独的rightSkewRDD
  • 将leftSkewRDD与rightSkewRDD进行Join,并将并行度设置为48,且在Join过程中将随机前缀去掉,得到倾斜数据集的Join结果skewedJoinRDD
  • 将leftRDD中不包含倾斜Key的数据抽取出来作为单独的leftUnSkewRDD
  • 对leftUnSkewRDD与原始的rightRDD进行Join,并行度也设置为48,得到Join结果unskewedJoinRDD
  • 通过union算子将skewedJoinRDD与unskewedJoinRDD进行合并,从而得到完整的Join结果集

具体实现代码如下

 1 public class SparkDataSkew{
 2 public static void main(String[] args) {
 3 int parallelism = 48;
 4 SparkConf sparkConf = new SparkConf();
 5 sparkConf.setAppName("SolveDataSkewWithRandomPrefix");
 6 sparkConf.set("spark.default.parallelism", parallelism + "");
 7 JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);
 8  
 9 JavaPairRDD<String, String> leftRDD = javaSparkContext.textFile("hdfs://hadoop1:8020/apps/hive/warehouse/default/test/")
10 .mapToPair((String row) -> {
11 String[] str = row.split(",");
12 return new Tuple2<String, String>(str[0], str[1]);
13 });
14  
15 JavaPairRDD<String, String> rightRDD = javaSparkContext.textFile("hdfs://hadoop1:8020/apps/hive/warehouse/default/test_new/")
16 .mapToPair((String row) -> {
17 String[] str = row.split(",");
18 return new Tuple2<String, String>(str[0], str[1]);
19 });
20  
21 String[] skewedKeyArray = new String[]{"9500048", "9500096"};
22 Set<String> skewedKeySet = new HashSet<String>();
23 List<String> addList = new ArrayList<String>();
24 for(int i = 1; i <=24; i++) {
25 addList.add(i + "");
26 }
27 for(String key : skewedKeyArray) {
28 skewedKeySet.add(key);
29 }
30  
31 Broadcast<Set<String>> skewedKeys = javaSparkContext.broadcast(skewedKeySet);
32 Broadcast<List<String>> addListKeys = javaSparkContext.broadcast(addList);
33  
34 JavaPairRDD<String, String> leftSkewRDD = leftRDD
35 .filter((Tuple2<String, String> tuple) -> skewedKeys.value().contains(tuple._1()))
36 .mapToPair((Tuple2<String, String> tuple) -> new Tuple2<String, String>((new Random().nextInt(24) + 1) + "," + tuple._1(), tuple._2()));
37  
38 JavaPairRDD<String, String> rightSkewRDD = rightRDD.filter((Tuple2<String, String> tuple) -> skewedKeys.value().contains(tuple._1()))
39 .flatMapToPair((Tuple2<String, String> tuple) -> addListKeys.value().stream()
40 .map((String i) -> new Tuple2<String, String>( i + "," + tuple._1(), tuple._2()))
41 .collect(Collectors.toList())
42 .iterator()
43 );
44  
45 JavaPairRDD<String, String> skewedJoinRDD = leftSkewRDD
46 .join(rightSkewRDD, parallelism)
47 .mapToPair((Tuple2<String, Tuple2<String, String>> tuple) -> new Tuple2<String, String>(tuple._1().split(",")[1], tuple._2()._2()));
48  
49 JavaPairRDD<String, String> leftUnSkewRDD = leftRDD.filter((Tuple2<String, String> tuple) -> !skewedKeys.value().contains(tuple._1()));
50 JavaPairRDD<String, String> unskewedJoinRDD = leftUnSkewRDD.join(rightRDD, parallelism).mapToPair((Tuple2<String, Tuple2<String, String>> tuple) -> new Tuple2<String, String>(tuple._1(), tuple._2()._2()));
51  
52 skewedJoinRDD.union(unskewedJoinRDD).foreachPartition((Iterator<Tuple2<String, String>> iterator) -> {
53 AtomicInteger atomicInteger = new AtomicInteger();
54 iterator.forEachRemaining((Tuple2<String, String> tuple) -> atomicInteger.incrementAndGet());
55 });
56  
57 javaSparkContext.stop();
58 javaSparkContext.close();
59 }
60 }

通过分析Join Stage的所有Task可知从下图可看出,整个Join耗时58秒,其中Join Stage耗时33秒。
few skewed key join

  • 由于Join分倾斜数据集Join和非倾斜数据集Join,而各Join的并行度均为48,故总的并行度为96
  • 由于提交任务时,设置的Executor个数为4,每个Executor的core数为12,故可用Core数为48,所以前48个Task同时启动(其Launch时间相同),后48个Task的启动时间各不相同(等待前面的Task结束才开始)
  • 由于倾斜Key被加上随机前缀,原本相同的Key变为不同的Key,被分散到不同的Task处理,故在所有Task中,未发现所处理数据集明显高于其它Task的情况

few skewed key join

实际上,由于倾斜Key与非倾斜Key的操作完全独立,可并行进行。而本实验受限于可用总核数为48,可同时运行的总Task数为48,故而该方案只是将总耗时减少一半(效率提升一倍)。如果资源充足,可并发执行Task数增多,该方案的优势将更为明显。在实际项目中,该方案往往可提升数倍至10倍的效率。

总结

适用场景
两张表都比较大,无法使用Map则Join。其中一个RDD有少数几个Key的数据量过大,另外一个RDD的Key分布较为均匀。

解决方案
将有数据倾斜的RDD中倾斜Key对应的数据集单独抽取出来加上随机前缀,另外一个RDD每条数据分别与随机前缀结合形成新的RDD(相当于将其数据增到到原来的N倍,N即为随机前缀的总个数),然后将二者Join并去掉前缀。然后将不包含倾斜Key的剩余数据进行Join。最后将两次Join的结果集通过union合并,即可得到全部Join结果。

优势
相对于Map则Join,更能适应大数据集的Join。如果资源充足,倾斜部分数据集与非倾斜部分数据集可并行进行,效率提升明显。且只针对倾斜部分的数据做数据扩展,增加的资源消耗有限。

劣势
如果倾斜Key非常多,则另一侧数据膨胀非常大,此方案不适用。而且此时对倾斜Key与非倾斜Key分开处理,需要扫描数据集两遍,增加了开销。

大表随机添加N种随机前缀,小表扩大N倍

原理

如果出现数据倾斜的Key比较多,上一种方法将这些大量的倾斜Key分拆出来,意义不大。此时更适合直接对存在数据倾斜的数据集全部加上随机前缀,然后对另外一个不存在严重数据倾斜的数据集整体与随机前缀集作笛卡尔乘积(即将数据量扩大N倍)。
spark random prefix

案例

这里给出示例代码,读者可参考上文中分拆出少数倾斜Key添加随机前缀的方法,自行测试。

 1 public class SparkDataSkew {
 2 public static void main(String[] args) {
 3 SparkConf sparkConf = new SparkConf();
 4 sparkConf.setAppName("ResolveDataSkewWithNAndRandom");
 5 sparkConf.set("spark.default.parallelism", parallelism + "");
 6 JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);
 7  
 8 JavaPairRDD<String, String> leftRDD = javaSparkContext.textFile("hdfs://hadoop1:8020/apps/hive/warehouse/default/test/")
 9 .mapToPair((String row) -> {
10 String[] str = row.split(",");
11 return new Tuple2<String, String>(str[0], str[1]);
12 });
13  
14 JavaPairRDD<String, String> rightRDD = javaSparkContext.textFile("hdfs://hadoop1:8020/apps/hive/warehouse/default/test_new/")
15 .mapToPair((String row) -> {
16 String[] str = row.split(",");
17 return new Tuple2<String, String>(str[0], str[1]);
18 });
19  
20 List<String> addList = new ArrayList<String>();
21 for(int i = 1; i <=48; i++) {
22 addList.add(i + "");
23 }
24  
25 Broadcast<List<String>> addListKeys = javaSparkContext.broadcast(addList);
26  
27 JavaPairRDD<String, String> leftRandomRDD = leftRDD.mapToPair((Tuple2<String, String> tuple) -> new Tuple2<String, String>(new Random().nextInt(48) + "," + tuple._1(), tuple._2()));
28  
29 JavaPairRDD<String, String> rightNewRDD = rightRDD
30 .flatMapToPair((Tuple2<String, String> tuple) -> addListKeys.value().stream()
31 .map((String i) -> new Tuple2<String, String>( i + "," + tuple._1(), tuple._2()))
32 .collect(Collectors.toList())
33 .iterator()
34 );
35  
36 JavaPairRDD<String, String> joinRDD = leftRandomRDD
37 .join(rightNewRDD, parallelism)
38 .mapToPair((Tuple2<String, Tuple2<String, String>> tuple) -> new Tuple2<String, String>(tuple._1().split(",")[1], tuple._2()._2()));
39  
40 joinRDD.foreachPartition((Iterator<Tuple2<String, String>> iterator) -> {
41 AtomicInteger atomicInteger = new AtomicInteger();
42 iterator.forEachRemaining((Tuple2<String, String> tuple) -> atomicInteger.incrementAndGet());
43 });
44  
45 javaSparkContext.stop();
46 javaSparkContext.close();
47 }
48 }

总结 

适用场景
一个数据集存在的倾斜Key比较多,另外一个数据集数据分布比较均匀。

优势
对大部分场景都适用,效果不错。

劣势
需要将一个数据集整体扩大N倍,会增加资源消耗。

总结

对于数据倾斜,并无一个统一的一劳永逸的方法。更多的时候,是结合数据特点(数据集大小,倾斜Key的多少等)综合使用上文所述的多种方法。

转载于:https://www.cnblogs.com/zuizui1204/p/7920692.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/354497.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaParser入门:以编程方式分析Java代码

我最喜欢的事情之一是解析代码并对其执行自动操作。 因此&#xff0c;我开始为JavaParser做出贡献&#xff0c;并创建了两个相关项目&#xff1a; java-symbol-solver和Effectivejava 。 作为JavaParser的贡献者&#xff0c;我反复阅读了一些非常类似的问题&#xff0c;这些问…

GoldenGate Logdump基本使用

Logdump是GoldenGate复制软件中附带的一个工具软件&#xff0c;在OGG的目录下可以找到。这个工具主要用于分析OGG生成的队列文件&#xff0c;查找记录、统计队列文件中的数据等。 在OGG安装目录下执行logdump.exe or ./logdump即可进入命令行。 开始查找记录之前&#xff0c;先…

.bam.bai的意义_业务活动监视器(BAM)2.0带来的革命

.bam.bai的意义生产兼具精益和企业价值的中间件是一项艰巨的工作。 它要么不存在&#xff0c;要么需要创新的思维&#xff08;很多&#xff09;&#xff0c;并且需要在实现中反复进行。 业务风险很大&#xff0c;但是如果您做对了&#xff0c;它就会使您领先于其他任何公司。 这…

数据结构和算法之排序五:选择排序

我们上一篇谈到了冒泡排序&#xff0c;其实我也说了&#xff0c;这两个排序方式何其相似&#xff0c;如果掌握了冒泡排序再来进行选择排序的理解我觉得完全没有太大的问题。那么什么叫做选择排序呢&#xff1f;我们可以理解为矮子里面挑高个&#xff0c;比如说呀有一个富翁来到…

Visual Studio Code使用问题

1、打开vscode黑屏 右击vscode快捷方式–>属性–>兼容性—>兼容模式打钩 重启vscode就可以了。 2、vscode终端没有显示路径&#xff0c;不能输入 显示如下图 则关闭VS Code ,右键单击VS Code 图标&#xff0c;选择属性->兼容性&#xff0c;取消勾选 已兼容模式运…

Java社区调查结果:74%的开发人员希望减少详细程度

一个新的JDK增强建议&#xff08;JEP&#xff09;在Java社区中风起云涌&#xff1a;JEP286。该建议建议在Java的未来版本中引入局部变量类型推断&#xff0c;以简化Java应用程序的编写。 在下面的文章中&#xff0c;我们将解释它的含义以及它将如何影响您的代码。 新帖&#…

coherence安装_Oracle Coherence:分布式数据管理

coherence安装本文介绍如何使用Oracle Coherence提供分布式&#xff08;分区&#xff09;数据管理。 在下面的示例应用程序中&#xff0c;创建了一个名为OTV的新集群&#xff0c;并且在该集群的两个成员之间分配了一个名为user-map的缓存对象。 二手技术&#xff1a; JDK 1.6.…

JavaFX技巧来节省内存! 属性和可观察物的阴影场

在 JavaFX的世界中&#xff0c; Properties API允许UI开发人员将值绑定到UI控件。 这种功能非常容易&#xff0c;但是当对象模型经常使用属性时&#xff0c;应用程序可能会很快耗尽内存。 我通常会编写两个单独的对象&#xff0c;例如pojo类和表示模型对象。 此技术通常在基于S…

如何在Hibernate Search 5.5.2 / Apache Lucene 5.4.x中处理停用词?

停用词&#xff0c;例如[“ a”&#xff0c;“ an”&#xff0c;“ and”&#xff0c;“ are”&#xff0c;“ as”&#xff0c;“ at”&#xff0c;“ be”&#xff0c;“ but”&#xff0c;“ by”&#xff0c;“ for”&#xff0c;“ if”&#xff0c;“在”&#xff0c;“成…

Java----前端验证之验证码额实现

验证码是常用的登录验证方式之一,最大的作用就是保证安全,验证码的生成在java中实现的方式有很多种,比如后台生成传输到前端页面,在前台直接生成进行验证,下面写一个最简单实现验证码验证登录的例子. 生成验证码: 验证码验证逻辑: From表单登录: 没错,就这么的简单.在scripts生…

使用Spring Boot隔离集成测试和模拟依赖项

集成测试可能很慢且不可靠&#xff0c;因为它们依赖于系统中过多的组件。 在某种程度上&#xff0c;这是不可避免的&#xff1a;这里的集成测试是为了验证系统的每个部分如何与其他内部或外部组件一起玩。 但是&#xff0c;我们可以通过仅分解所需的依赖关系而不是整个系统来改…

Ubuntu 16.04下使用Wine安装Xshell 4和Xftp 4

说明&#xff1a; 1、使用的Wine版本是深度出品&#xff08;Deepin&#xff09;&#xff0c;已经精简了很多没用的配置&#xff0c;使启动能非常快&#xff0c;占用资源小。 2、由于Xshell 5的C库无法在这个Wine版本运行&#xff0c;即使升级官方原版的2版本也无法解决&#xf…

电脑缺失MSVCP110.dll文件

安装某软件显示如下错误。 错误&#xff1a; 原因&#xff1a;电脑缺少MSVCP110.dll系统文件。C:\Windows\System32目录下没有此文件。 解决&#xff1a; 下载vcredist_x64直接双击安装&#xff0c;安装完成后就可以继续安装之前安装不了的软件了。。 这里是我下载的&#…

在WildFly的REST Web服务中与Jackson的双向关系

这是使用Jackson的REST Web服务中Java实体之间的双向关系的示例。 假设我们在两个实体Parent和Child之间存在双向关系。 使用MySQL工作台为这两个表生成SQL模式文件。 DROP SCHEMA IF EXISTS bidirectional_schema ; CREATE SCHEMA IF NOT EXISTS bidirectional_schema DEFA…

Postman安装与使用(网络请求神器)--post、get请求

安装 1、Postman最早是作用chrome浏览器插件存在的&#xff0c;所以&#xff0c;你可以到chrome商店搜索下载安装&#xff0c;因为重所周知的原因&#xff0c;所以&#xff0c;大家都会找别人共享的postman插件文件来安装。由于2018年初Chrome停止对Chrome应用程序的支持。 官…

openshift用户管理_OpenShift Express Web管理控制台:入门

openshift用户管理本周&#xff0c; 最新版本的OpenShift为已经很棒的PaaS Cloud提供商带来了两个非常好的功能。 首先&#xff0c;JBoss AS已从7.0升级到7.1&#xff0c;并且所有新的Express Web Management Console已作为预览发布。 在本文中&#xff0c;我们将研究如何使用此…

linux系统搭建ftp服务器--只给某个用户访问其默认目录下的文件

1、环境: window操作系统中安装FlashFXP 软件或xftp&#xff1b; 服务器端的操作系统为centos8&#xff1b; 2、检查安装vsftpd软件 查看所有的安装的软件包 并在结果中查找包含vsftp 的文件 rpm -qa | grep vsftpd如果没有装则使用yum命令安装 yum -y install vsftpd3、创…

Openshift源中的高可用性Drools无状态服务

嗨&#xff0c;大家好&#xff01; 在这篇博客文章中&#xff0c;我想举一个简单的例子&#xff0c;展示使用Openshift 3&#xff08;Docker和Kubernetes&#xff09;扩展Drools Stateless服务有多么容易。 我将展示如何通过按需提供新实例来扩展我们的服务&#xff0c;以及如何…

jpa jsf_完整的Web应用程序Tomcat JSF Primefaces JPA Hibernate –第1部分

jpa jsf我们创建了这篇文章&#xff0c;将展示如何使用以下工具创建完整的Web应用程序&#xff1a;Tomcat7&#xff0c;带有Primefaces的JSF2&#xff08;Facelets和Libraries&#xff09;&#xff08;具有AutoComplete&#xff09;&#xff0c;JPA / Hibernate&#xff08;具有…

错题

1. 本题考查String对象的声明和赋值方式。C#中没有new String() 这种方式来构造字符串。故选 AC 2. 在CSS中&#xff0c;控制列表样式的属性有&#xff1a;list-style-type&#xff0c;list-style-position&#xff0c;list-style-image&#xff0c;list-style equals比较的是像…