Spark Programming--- Shuffle operations
*:first-child {
margin-top: 0 !important; }
body > *:last-child {
margin-bottom: 0 !important; }
a {
color: #4183C4; }
a.absent {
color: #cc0000; }
a.anchor {
display: block;
padding-left: 30px;
margin-left: -30px;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
bottom: 0; }
h1, h2, h3, h4, h5, h6 {
margin: 20px 0 10px;
padding: 0;
font-weight: bold;
-webkit-font-smoothing: antialiased;
cursor: text;
position: relative; }
h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA09pVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoMTMuMCAyMDEyMDMwNS5tLjQxNSAyMDEyLzAzLzA1OjIxOjAwOjAwKSAgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OUM2NjlDQjI4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OUM2NjlDQjM4ODBGMTFFMTg1ODlEODNERDJBRjUwQTQiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo5QzY2OUNCMDg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo5QzY2OUNCMTg4MEYxMUUxODU4OUQ4M0REMkFGNTBBNCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PsQhXeAAAABfSURBVHjaYvz//z8DJYCRUgMYQAbAMBQIAvEqkBQWXI6sHqwHiwG70TTBxGaiWwjCTGgOUgJiF1J8wMRAIUA34B4Q76HUBelAfJYSA0CuMIEaRP8wGIkGMA54bgQIMACAmkXJi0hKJQAAAABJRU5ErkJggg==) no-repeat 10px center;
text-decoration: none; }
h1 tt, h1 code {
font-size: inherit; }
h2 tt, h2 code {
font-size: inherit; }
h3 tt, h3 code {
font-size: inherit; }
h4 tt, h4 code {
font-size: inherit; }
h5 tt, h5 code {
font-size: inherit; }
h6 tt, h6 code {
font-size: inherit; }
h1 {
font-size: 28px;
color: black; }
h2 {
font-size: 24px;
border-bottom: 1px solid #cccccc;
color: black; }
h3 {
font-size: 18px; }
h4 {
font-size: 16px; }
h5 {
font-size: 14px; }
h6 {
color: #777777;
font-size: 14px; }
p, blockquote, ul, ol, dl, li, table, pre {
margin: 15px 0; }
hr {
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxAEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;
border: 0 none;
color: #cccccc;
height: 4px;
padding: 0;
}
body > h2:first-child {
margin-top: 0;
padding-top: 0; }
body > h1:first-child {
margin-top: 0;
padding-top: 0; }
body > h1:first-child + h2 {
margin-top: 0;
padding-top: 0; }
body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
margin-top: 0;
padding-top: 0; }
a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
margin-top: 0;
padding-top: 0; }
h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
margin-top: 0; }
li p.first {
display: inline-block; }
li {
margin: 0; }
ul, ol {
padding-left: 30px; }
ul :first-child, ol :first-child {
margin-top: 0; }
dl {
padding: 0; }
dl dt {
font-size: 14px;
font-weight: bold;
font-style: italic;
padding: 0;
margin: 15px 0 5px; }
dl dt:first-child {
padding: 0; }
dl dt > :first-child {
margin-top: 0; }
dl dt > :last-child {
margin-bottom: 0; }
dl dd {
margin: 0 0 15px;
padding: 0 15px; }
dl dd > :first-child {
margin-top: 0; }
dl dd > :last-child {
margin-bottom: 0; }
blockquote {
border-left: 4px solid #dddddd;
padding: 0 15px;
color: #777777; }
blockquote > :first-child {
margin-top: 0; }
blockquote > :last-child {
margin-bottom: 0; }
table {
padding: 0;border-collapse: collapse; }
table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
table tr:nth-child(2n) {
background-color: #f8f8f8; }
table tr th {
font-weight: bold;
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }
table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }
table tr th :first-child, table tr td :first-child {
margin-top: 0; }
table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }
img {
max-width: 100%; }
span.frame {
display: block;
overflow: hidden; }
span.frame > span {
border: 1px solid #dddddd;
display: block;
float: left;
overflow: hidden;
margin: 13px 0 0;
padding: 7px;
width: auto; }
span.frame span img {
display: block;
float: left; }
span.frame span span {
clear: both;
color: #333333;
display: block;
padding: 5px 0 0; }
span.align-center {
display: block;
overflow: hidden;
clear: both; }
span.align-center > span {
display: block;
overflow: hidden;
margin: 13px auto 0;
text-align: center; }
span.align-center span img {
margin: 0 auto;
text-align: center; }
span.align-right {
display: block;
overflow: hidden;
clear: both; }
span.align-right > span {
display: block;
overflow: hidden;
margin: 13px 0 0;
text-align: right; }
span.align-right span img {
margin: 0;
text-align: right; }
span.float-left {
display: block;
margin-right: 13px;
overflow: hidden;
float: left; }
span.float-left span {
margin: 13px 0 0; }
span.float-right {
display: block;
margin-left: 13px;
overflow: hidden;
float: right; }
span.float-right > span {
display: block;
overflow: hidden;
margin: 13px auto 0;
text-align: right; }
code, tt {
margin: 0 2px;
padding: 0 5px;
white-space: nowrap;
border: 1px solid #eaeaea;
background-color: #f8f8f8;
border-radius: 3px; }
pre code {
margin: 0;
padding: 0;
white-space: pre;
border: none;
background: transparent; }
.highlight pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px; }
pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
font-size: 13px;
line-height: 19px;
overflow: auto;
padding: 6px 10px;
border-radius: 3px; }
pre code, pre tt {
background-color: transparent;
border: none; }
sup {
font-size: 0.83em;
vertical-align: super;
line-height: 0;
}
kbd {
display: inline-block;
padding: 3px 5px;
font-size: 11px;
line-height: 10px;
color: #555;
vertical-align: middle;
background-color: #fcfcfc;
border: solid 1px #ccc;
border-bottom-color: #bbb;
border-radius: 3px;
box-shadow: inset 0 -1px 0 #bbb
}
* {
-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
body {
width: 854px;
margin:0 auto;
}
}
@media print {
table, pre {
page-break-inside: avoid;
}
pre {
word-wrap: break-word;
}
}
-->
Spark Programming--- Shuffle operations
http://spark.apache.org/docs/latest/rdd-programming-guide.html#shuffle-operations
一些spark的特定操作将会触发被称为shuffle的事件。Shuffle是Spark用于重新分布数据的机制,这样可以在不同的分区来分组。这通常涉及到在executor和机器之间进行拷贝数据,所以shuffle是一个很复杂并且消耗高的操作。
背景
为了了解shuffle期间发生了什么,我们可以考虑reduceByKey操作作为例子。reduceByKey操作生成了一个新的RDD通过所有的单个键值组合为一个元组-关键字和针对与该关键字相关的所有值执行reduce函数的结果。这里的挑战不是所有的值对一个单独的键都在同一个分区上或者甚至说在一台机器上,而是它们必须被重新分布来计算结果。
在Spark,数据通常不会跨分区分布到特定操作的必要位置。在计算中,一个单独的任务将会在一个单独的分区上操作-然而为了组织所有的数据来被一个的单独reduceByKey 的reduce任务来执行,Spark需要来执行一个all-to-all操作。它必须读取所有分区来找到所有键的值,然后将它们带到一起跨分区来为每一个键计算最终的结果---这个被称为shuffle。
尽管在每一个分区中的新的shuffled数据的元素集是很重要的,同样分区自己的顺序也很重要,而元素之间的顺序就不是了。如果一个想要预测shuffle中的顺序数据那么可以使用:
- mapPartitions 来排序每一个分区,比如,.sorted
- repartitionAndSortWithinPartitions 来有效分区同时同步重新分区。
- sortBy 创造一个全局的排序的RDD
可以引起一个shuffle 的操作包括:repartition 和 coalesce,ByKey的操作,除了counting之外的比如:groupByKey 和reduceByKey,以及join操作比如cogroup 和 join。
性能影响
Shuffle是一个昂贵的操作因为它涉及到磁盘I/O,数据序列化和网络I/O。为了给shuffle组织数据,spark生成一系列任务-maps用于组织数据,以及一系列reduce任务来聚集它。这个命名系统来自于MapReduce而且并不直接和SparK的map,reduce操作有关。
在内部,单独的map任务的结果会被保存在内存中直到它们不适用。然后这些结果会被根据目标分区排序并且写向单一的文件。在reduce方面,任务读取相关的排序块。
一定的shuffle操作会消耗明显的数量的堆内存因为它们使用的是在内存中的数据结构来组织记录在传输之前或者之后。明显的,reduceByKey和AggregateByKey创造了这些结构在map阶段,以及 ‘Bykey的操作生成了它们在reduce阶段。当数据不能放进内存中时,Spark将会将这些表散落到硬盘中,会引起而外的磁盘I/O和增加垃圾回收次数。
Shuffle同样会生成大量的中间文件在磁盘中。从Spark1.3开始,这些文件被保存直到对应的RDDs不再被使用以及已经被垃圾回收了。这样做是为了shuffle文件不需要被重新创造如果lineage被重新计算时。垃圾回收也许会发生只有在一段很长时间,如果这个应用保留了对RDD的引用或者如果GC没有频繁的发生。这意味着长期运行的spark任务也许会消耗大量的磁盘空间。这个零时的磁盘目录会被spark.local.dir参数所指定。
Shuffle行为可以被调整通过一系列的参数。可以参考Spark Configuration Guide.‘Shuffle Behavior’章节。
Shuffle Behavior
属性名称Property Name | 默认值Default | 含义Meaning |
---|---|---|
spark.reducer.maxSizeInFlight | 48m | 从每一个reduce任务中同步获取的map输出的最大值。由于每一个输出需要我们创造一个缓存来接受它,这个代表了每个任务的固定的内存开销,所以尽量保证它较小除非你有很多内存。 |
spark.reducer.maxReqsInFlight | Int.MaxValue | 这个配置限制了任意给定点远程请求获取块数。当集群中的主机数量增加的时候,它也许会导致一个非常大数量的内部连接到一到多个节点,引起worker在负载下失败。通过允许它来限制获取请求的数量,这个情况也许会缓解 |
spark.reducer.maxBlocksInFlightPerAddress | Int.MaxValue | 这个配置限制了每一个从给定端口里的的reduce任务可以获取的远程端口数量。当一个大量的block被一个给定的地址在一次单独获取或者同步获取所请求时,可能会冲垮服务的executor或者Node Manager。这个配置对于减少Node Manager的负载尤为有用当外部的shuffle是被允许的。你可以通过设定一个较低值来减轻这个情况。 |
spark.maxRemoteBlockSizeFetchToMem | Long.MaxValue | 远程的块将会被获取到磁盘中,当这个块的大小超过了这个配置的值在byte单位上。这个用于避免一个巨大的请求占据了太多的内存。我们可以将这个配置为一个指定的值(比如,200M)。注意到这个配置将会影响到shuffle的获取以及远程块获取的块管理。对于允许了外部shuffle服务的用户,这个特性只会在外部shuffle服务版本高于Spark2。2时有效。 |
spark.shuffle.compress | true | 是否压缩map的输出文件,通常是一个好想法。压缩将会使用spark.io.compression.codec. |
spark.shuffle.file.buffer | 32k | 对每一个shuffle文件输出流的在内存中的缓存大小,单位是KiB除非有其他的特别指定。这些缓存减少了硬盘查找和系统调用创建中间shuffle文件的过程。 |
spark.shuffle.io.maxRetries | 3 | (Netty only)最大自动重复尝试的次数如果这个值没有被设置为0.这个重试逻辑有助于稳定大型的shuffle在长时间的GC暂停或者暂时的网络连接问题上。 |
spark.shuffle.io.numConnectionsPerPeer | 1 | (Netty only) 节点之间的连接的重复使用为了减少大型集群中重复建立连接的情况。对于有很多硬盘和很少主机的集群,这个将会导致并发行不足以饱和所有硬盘,因此用户可能会考虑增加这个值。 |
spark.shuffle.io.preferDirectBufs | true | (Netty only) 堆外缓冲区在shuffle和缓存块转移期间被用于减少垃圾回收。对于对外缓存内存数量有限的环境,用户也许想要关掉这个来强迫所有的来自于Netty的分配都是在堆上。 |
spark.shuffle.io.retryWait | 5s | (Netty only) 在每一次重试直接需要等待多久。最大的延迟时间默认是15秒,maxRetries * retryWait. |
spark.shuffle.service.enabled | false | 允许外部shuffle服务。这个服务保存了通过executor所写的shuffle文件,这样这个executor可以安全的被移除。这个配置必须被允许如果spark.dynamicAllocation.enabled是“true”。这个外部的shuffle服务必须被启动。查看dynamic allocation configuration and setup documentation来获得更多信息。 |
spark.shuffle.service.port | 7337 | 外部shuffle服务将会运行的端口。 |
spark.shuffle.service.index.cache.size | 100m | 缓存条目限制在指定的内存占用空间中,以字节为单位 |
spark.shuffle.maxChunksBeingTransferred | Long.MAX_VALUE | 在shuffle服务中同一时间最大允许传输的块数量。注意到新来的连接将会被关闭如果达到了最大数量。这个客户端将会尝试重新连接根据shuffle的重试配置(see spark.shuffle.io.maxRetries and spark.shuffle.io.retryWait),如果这个限制也被达到了,那么这个任务将会失败。 |
spark.shuffle.sort.bypassMergeThreshold | 200 | (Advanced)在基于排序的shuffle管理中,避免合并排序数据如果这里没有map-side的聚合和这里最多有配置的这么多的reduce分区。 |
spark.shuffle.spill.compress | true | 是否压缩溢出的数据在shuffle期间 |
spark.shuffle.accurateBlockThreshold | 100 * 1024 * 1024 | 阀值是以bytes为单位,高于此值将准确记录HighlyCompressedMapStatus中的shuffle块的大小。这个用于帮助阻止OOM通过避免错误估计了shuffle块大小当获取了shuffle块时。 |
spark.shuffle.registration.timeout | 5000 | 注册外部shuffle服务的超时时间,单位是毫秒 |
spark.shuffle.registration.maxAttempts | 3 | 当注册外部shuffle服务失败的时候,我们会重复尝试的最大次数 |
spark.io.encryption.enabled | false | 允许IO编码。目前支持所有的模式除了Mesos。当使用这个特性的时候,我们推荐RPC编码。 |
spark.io.encryption.keySizeBits | 128 | IO编码的值大小单位为bit。支持的值有128,192和256. |
spark.io.encryption.keygen.algorithm | HmacSHA1 | 当生成一个IO编码键值时使用的算法。被支持的算法在Java Cryptography Architecture Standard Algorithm Name 文档的KeyGenerator章节中被描述。 |
Spark Programming--- Shuffle operations的更多相关文章
- Spark Programming Guide《翻译》
转载必须注明出处:梁杰帆 在这里要先感谢原作者们!如果各位在这里发现了错误之处,请大家提出 1.Initializing Spark Spark程序必须做的第一件事就是创建一个SparkCon ...
- spark.sql.shuffle.partitions和spark.default.parallelism的区别
在关于spark任务并行度的设置中,有两个参数我们会经常遇到,spark.sql.shuffle.partitions 和 spark.default.parallelism, 那么这两个参数到底有什 ...
- 【Spark】Spark的Shuffle机制
MapReduce中的Shuffle 在MapReduce框架中,shuffle是连接Map和Reduce之间的桥梁,Map的输出要用到Reduce中必须经过shuffle这个环节,shuffle的性 ...
- 【Spark篇】---Spark中Shuffle文件的寻址
一.前述 Spark中Shuffle文件的寻址是一个文件底层的管理机制,所以还是有必要了解一下的. 二.架构图 三.基本概念: 1) MapOutputTracker MapOutputTracker ...
- 【Spark篇】---Spark中Shuffle机制,SparkShuffle和SortShuffle
一.前述 Spark中Shuffle的机制可以分为HashShuffle,SortShuffle. SparkShuffle概念 reduceByKey会将上一个RDD中的每一个key对应的所有val ...
- Spark 的 Shuffle过程介绍`
Spark的Shuffle过程介绍 Shuffle Writer Spark丰富了任务类型,有些任务之间数据流转不需要通过Shuffle,但是有些任务之间还是需要通过Shuffle来传递数据,比如wi ...
- 研究一下Spark Hash Shuffle 和 SortShuffle 原理机制
研究一下Spark Hash Shuffle 和 SortShuffle 原理机制研究一下Spark Hash Shuffle 和 SortShuffle 原理机制研究一下Spark Hash Shu ...
- 剖析Hadoop和Spark的Shuffle过程差异
一.前言 对于基于MapReduce编程范式的分布式计算来说,本质上而言,就是在计算数据的交.并.差.聚合.排序等过程.而分布式计算分而治之的思想,让每个节点只计算部分数据,也就是只处理一个分片,那么 ...
- [Spark]What's the difference between spark.sql.shuffle.partitions and spark.default.parallelism?
From the answer here, spark.sql.shuffle.partitions configures the number of partitions that are used ...
- spark的shuffle机制
对于大数据计算框架而言,Shuffle阶段的设计优劣是决定性能好坏的关键因素之一.本文将介绍目前Spark的shuffle实现,并将之与MapReduce进行简单对比.本文的介绍顺序是:shuffle ...
随机推荐
- jsp2
jsp:实现了静态html中,插入了动态的代码 servlet:动态代码中,插入静态html (jsp代码) <%@ page language="java" content ...
- 关于fftshift----将零频率的分量移到频谱的中心
fftshift 作用:将零频点移到频谱的中间 用法: Y=fftshift(X) Y=fftshift(X,dim) 描述:fftshift移动零频点到频谱中间,重新排列fft,fft2和fftn的 ...
- 010 Editor 8.0.1 之 逆向分析及注册机编写
前言一.工具及软件介绍二.逆向分析2.1.找到提示错误注册弹窗2.2.分析跳转处代码2.3.=2D 函数分析2.3.1.获取注册码处分析2.3.2.3处分支分析2.3.2.1.9C情况2.3.2.2. ...
- redis get乱码
- google搜索引擎正确打开姿势
Google搜索引擎 原文来自黑白之道微信公众号 https://mp.weixin.qq.com/s/Ey_ODP_mG00of5DPwcQtfg 这里之所以要介绍google搜索引 ...
- Ubuntu 18.04 下如何配置mysql 及 配置远程连接
首先是大家都知道的老三套,啥也不说上来就放三个大招: sudo apt-get install mysql-server sudo apt isntall mysql-client sudo apt ...
- ClassLoader的工作机制
本文中主要介绍类加载器的工作机制 一:首先什么是类加载器? 类加载器就是用来加载java类到java虚拟机中.java源程序经过编译之后形成字节码文件,类加载器将字节码文件加载到内存中,并转换成jav ...
- [精华][推荐] CAS SSO单点登录环境搭建及实例
1.因为是本地模拟sso环境,而sso的环境测试需要域名,所以需要虚拟几个域名出来,步骤如下: 2.进入目录C:\Windows\System32\drivers\etc 3.修改hosts文件 12 ...
- [JavaScript] 弹出编辑框
效果:单击图片copy,双击图片或者点Edit都会打开编辑窗口 Style <style> .black_overlay{ display: none; position: absolut ...
- 初学C的感想
既然是随笔,那就让我谈谈或者说聊聊自己的感想吧.刚刚进入大学的时候,对物联网工程这个专业挺迷茫的,至少我不知道自己将要学什么,只知道高数和英语是一定要学的,后来听学长说要学C语言,对这个概念很陌生,有 ...