当前位置: 首页 > 编程日记 > 正文

spark调优(一)-开发调优,数据倾斜,shuffle调优

主要分为开发调优、资源调优、数据倾斜调优、shuffle调优几个部分。

开发调优和资源调优是所有Spark作业都需要注意和遵循的一些基本原则,是高性能Spark作业的基础;数据倾斜调优,主要讲解了一套完整的用来解决Spark作业数据倾斜的解决方案;shuffle调优,面向的是对Spark的原理有较深层次掌握和研究的同学,主要讲解了如何对Spark作业的shuffle运行过程以及细节进行调优。

一:开发调优

在开发Spark作业的过程中注意和应用一些性能优化的基本原则;

调优的十大原则:

  • 原则一:避免创建重复的RDD
  • 原则二:尽可能复用同一个RDD
  • 原则三:对多次使用的RDD进行持久化
  • 原则四:尽量避免使用shuffle类算子

shuffle一般是运算过程中的瓶颈,shuffle过程就是把所有的集群节点上的key拉倒同一个节点上。进行聚合,join等操作。shuffle过程有个IO磁盘的过程,这个是非常影响其速度。熟悉mapreduce的也许知道,shuffle过程中会对key进行排序,对于大量key来说这个是消耗时间最长的一个过程。

所以,则尽可能避免使用reduceByKey、join、distinct、repartition等会进行shuffle的算子。如必须使用,先节点聚合等操作后,再节点之间进行聚合。类似于mapreduce中combine()类的功能。

尽量用reduceByKey代替groupByKey。

  • 原则五:使用map-side预聚合的shuffle操作
  • 原则六:使用高性能的算子
  • 原则七:广播大变量
  • 原则八:使用Kryo优化序列化性能
  • 原则九:优化数据结构
  • 原则十:Data Locality本地化级别

总结以上的原则可以总结成以下的几种:

1-减少重复算子,2-减少磁盘的io,3-减少网络传输数据,使用序列化。

二:数据倾斜调优

1-数据倾斜现象:

  • 绝大多数task执行得都非常快,但个别task执行极慢。比如,总共有1000个task,997个task都在1分钟之内执行完了,但是剩余两三个task却要一两个小时。这种情况很常见。

  • 原本能够正常执行的Spark作业,某天突然报出OOM(内存溢出)异常,观察异常栈,是我们写的业务代码造成的。这种情况比较少见。

2-数据倾斜发生的原理:

在进行shuffle的时候,必须将各个节点上相同的key拉取到某个节点上的一个task来进行处理,比如按照key进行聚合或join等操作。此时如果某个key对应的数据量特别大的话,就会发生数据倾斜。比如大部分key对应10条数据,但是个别key却对应了100万条数据。二整个spark的运行时间是由最慢的任务决定。

3-数据倾斜代码定位:

数据倾斜只会发生在shuffle过程中。这里给大家罗列一些常用的并且可能会触发shuffle操作的算子:distinct、groupByKey、reduceByKey、ggregateByKey、join、cogroup、repartition等。出现数据倾斜时,可能就是你的代码中使用了这些算子中的某一个所导致的。

数据倾斜stage定位之执行特别慢的情况:

这个阶段要了解最基本的stage划分的原理。

1-yarn-client模式提交:本地是直接可以看到log的,可以在log中找到当前运行到了第几个stage;

2-yarn-cluster模式提交:可以通过Spark Web UI来查看当前运行到了第几个stage。页面上会有详细的数据进行分析。包括运行时间,输入量,输出量等。

数据倾斜stage定位之执行OOM的情况:

建议直接看yarn-client模式下本地log的异常栈,或者是通过YARN查看yarn-cluster模式下的log中的异常栈。一般来说,通过异常栈信息就可以定位到你的代码中哪一行发生了内存溢出。然后在那行代码附近找找,一般也会有shuffle类算子,此时很可能就是这个算子导致了数据倾斜。

确定key的分布情况,针对不同情况设置不同的shuffle算子;

4-数据倾斜解决方案:

参考:https://www.cnblogs.com/qingyunzong/p/8946679.html

  • 解决方案一:使用Hive ETL预处理数据

对原有的key进行处理,生成新的key,对新key进行聚合等处理后。再进行聚合。治标不治本。

  • 解决方案二:过滤少数导致倾斜的key

就是舍弃少数的key

  • 解决方案三:提高shuffle操作的并行度

在对RDD执行shuffle算子时,给shuffle算子传入一个参数,比如reduceByKey(1000)。只是缓解了数据倾斜,并没有解决。

  • 解决方案四:两阶段聚合(局部聚合+全局聚合)

将原本相同的key通过附加随机前缀的方式,变成多个不同的key,就可以让原本被一个task处理的数据分散到多个task上去做局部聚合,进而解决单个task处理数据量过多的问题。接着去除掉随机前缀,再次进行全局聚合,就可以得到最终的结果。

  • 解决方案五:将reduce join转为map join

适用场景较少,因为这个方案只适用于一个大表和一个小表的情况。

  • 解决方案六:采样倾斜key并分拆join操作

适合两张大表join,其中一张大表的key分布比较均匀,另一张大表存在几个key的数据量比较大;实现方法是将数据量比较大的key使用方法五进行解决。

方案实现思路:

  • 对包含少数几个数据量过大的key的那个RDD,通过sample算子采样出一份样本来,然后统计一下每个key的数量,计算出来数据量最大的是哪几个key。
  • 然后将这几个key对应的数据从原来的RDD中拆分出来,形成一个单独的RDD,并给每个key都打上n以内的随机数作为前缀,而不会导致倾斜的大部分key形成另外一个RDD。
  • 接着将需要join的另一个RDD,也过滤出来那几个倾斜key对应的数据并形成一个单独的RDD,将每条数据膨胀成n条数据,这n条数据都按顺序附加一个0~n的前缀,不会导致倾斜的大部分key也形成另外一个RDD。
  • 再将附加了随机前缀的独立RDD与另一个膨胀n倍的独立RDD进行join,此时就可以将原先相同的key打散成n份,分散到多个task中去进行join了。
  • 而另外两个普通的RDD就照常join即可。
  • 最后将两次join的结果使用union算子合并起来即可,就是最终的join结果。
  • 解决方案七:使用随机前缀和扩容RDD进行join

方案适用场景:如果在进行join操作时,RDD中有大量的key导致数据倾斜,那么进行分拆key也没什么意义,此时就只能使用最后一种方案来解决问题了。

方案实现思路:

  • 该方案的实现思路基本和“解决方案六”类似,首先查看RDD/Hive表中的数据分布情况,找到那个造成数据倾斜的RDD/Hive表,比如有多个key都对应了超过1万条数据。
  • 然后将该RDD的每条数据都打上一个n以内的随机前缀。
  • 同时对另外一个正常的RDD进行扩容,将每条数据都扩容成n条数据,扩容出来的每条数据都依次打上一个0~n的前缀。
  • 最后将两个处理后的RDD进行join即可。
  • 解决方案八:多种方案组合使用

三:shuffle调优

参考文献:https://www.cnblogs.com/qingyunzong/p/8954552.html

强行引入一个问题:spark为什么要分区,分布式集群中,网络通信开销是非常大的,把大文件压缩成小文件进行传输(分区)。可以很大程度上降低网络开销。但会增加计算开销。

1-ShuffleManager发展概述

在Spark的源码中,负责shuffle过程的执行、计算和处理的组件主要就是ShuffleManager,也即shuffle管理器。而随着Spark的版本的发展,ShuffleManager也在不断迭代,变得越来越先进。

在Spark 1.2以前,默认的shuffle计算引擎是HashShuffleManager。该ShuffleManager而HashShuffleManager有着一个非常严重的弊端,就是会产生大量的中间磁盘文件,进而由大量的磁盘IO操作影响了性能。

因此在Spark 1.2以后的版本中,默认的ShuffleManager改成了SortShuffleManager。SortShuffleManager相较于HashShuffleManager来说,有了一定的改进。主要就在于,每个Task在进行shuffle操作时,虽然也会产生较多的临时磁盘文件,但是最后会将所有的临时文件合并(merge)成一个磁盘文件,因此每个Task就只有一个磁盘文件。在下一个stage的shuffle read task拉取自己的数据时,只要根据索引读取每个磁盘文件中的部分数据即可。

2-HashShufflleMannger运行原理:

改进前:

改进后:

3-SortShuffleManager运行原理

普通运行机制:

bypass运行机制:

而该机制与普通SortShuffleManager运行机制的不同在于:第一,磁盘写机制不同;第二,不会进行排序。也就是说,启用该机制的最大好处在于,shuffle write过程中,不需要进行数据的排序操作,也就节省掉了这部分的性能开销。

4-shuffle参数调整

见官网的more -> configuration,涉及到的主要参数:

  • spark.shuffle.file.buffer
  • spark.reducer.maxSizeInFlight
  • spark.shuffle.io.maxRetries
  • spark.shuffle.io.retryWait
  • spark.shuffle.sort.bypassMergeThreshold

四:资源调优

Spark的资源参数,基本都可以在spark-submit命令中作为参数设置。具体的参数意义参考官方文档。

3.1 num-executors

  • 参数说明:该参数用于设置Spark作业总共要用多少个Executor进程来执行。Driver在向YARN集群管理器申请资源时,YARN集群管理器会尽可能按照你的设置来在集群的各个工作节点上,启动相应数量的Executor进程。这个参数非常之重要,如果不设置的话,默认只会给你启动少量的Executor进程,此时你的Spark作业的运行速度是非常慢的。
  • 参数调优建议:每个Spark作业的运行一般设置50~100个左右的Executor进程比较合适,设置太少或太多的Executor进程都不好。设置的太少,无法充分利用集群资源;设置的太多的话,大部分队列可能无法给予充分的资源。

3.2 executor-memory

  • 参数说明:该参数用于设置每个Executor进程的内存。Executor内存的大小,很多时候直接决定了Spark作业的性能,而且跟常见的JVM OOM异常,也有直接的关联。
  • 参数调优建议:每个Executor进程的内存设置4G~8G较为合适。但是这只是一个参考值,具体的设置还是得根据不同部门的资源队列来定。可以看看自己团队的资源队列的最大内存限制是多少,num-executors乘以executor-memory,是不能超过队列的最大内存量的。此外,如果你是跟团队里其他人共享这个资源队列,那么申请的内存量最好不要超过资源队列最大总内存的1/3~1/2,避免你自己的Spark作业占用了队列所有的资源,导致别的同学的作业无法运行。

3.3 executor-cores

  • 参数说明:该参数用于设置每个Executor进程的CPU core数量。这个参数决定了每个Executor进程并行执行task线程的能力。因为每个CPU core同一时间只能执行一个task线程,因此每个Executor进程的CPU core数量越多,越能够快速地执行完分配给自己的所有task线程。
  • 参数调优建议:Executor的CPU core数量设置为2~4个较为合适。同样得根据不同部门的资源队列来定,可以看看自己的资源队列的最大CPU core限制是多少,再依据设置的Executor数量,来决定每个Executor进程可以分配到几个CPU core。同样建议,如果是跟他人共享这个队列,那么num-executors * executor-cores不要超过队列总CPU core的1/3~1/2左右比较合适,也是避免影响其他同学的作业运行。最好的应该就是一个cpu core对应两到三个task

3.4 driver-memory

  • 参数说明:该参数用于设置Driver进程的内存。
  • 参数调优建议:Driver的内存通常来说不设置,或者设置1G左右应该就够了。唯一需要注意的一点是,如果需要使用collect算子将RDD的数据全部拉取到Driver上进行处理,那么必须确保Driver的内存足够大,否则会出现OOM内存溢出的问题。

3.5 spark.default.parallelism

  • 参数说明:该参数用于设置每个stage的默认task数量。这个参数极为重要,如果不设置可能会直接影响你的Spark作业性能。一个分区对应一个task,也就是这个参数其实就是设置task的数量
  • 参数调优建议:Spark作业的默认task数量为500~1000个较为合适。很多同学常犯的一个错误就是不去设置这个参数,那么此时就会导致Spark自己根据底层HDFS的block数量来设置task的数量,默认是一个HDFS block对应一个task。通常来说,Spark默认设置的数量是偏少的(比如就几十个task),如果task数量偏少的话,就会导致你前面设置好的Executor的参数都前功尽弃。试想一下,无论你的Executor进程有多少个,内存和CPU有多大,但是task只有1个或者10个,那么90%的Executor进程可能根本就没有task执行,也就是白白浪费了资源!因此Spark官网建议的设置原则是,设置该参数为num-executors * executor-cores的2~3倍较为合适,比如Executor的总CPU core数量为300个,那么设置1000个task是可以的,此时可以充分地利用Spark集群的资源。

3.6 spark.storage.memoryFraction

  • 参数说明:该参数用于设置RDD持久化数据在Executor内存中能占的比例,默认是0.6。也就是说,默认Executor 60%的内存,可以用来保存持久化的RDD数据。根据你选择的不同的持久化策略,如果内存不够时,可能数据就不会持久化,或者数据会写入磁盘。
  • 参数调优建议:如果Spark作业中,有较多的RDD持久化操作,该参数的值可以适当提高一些,保证持久化的数据能够容纳在内存中。避免内存不够缓存所有的数据,导致数据只能写入磁盘中,降低了性能。但是如果Spark作业中的shuffle类操作比较多,而持久化操作比较少,那么这个参数的值适当降低一些比较合适。此外,如果发现作业由于频繁的gc导致运行缓慢(通过spark web ui可以观察到作业的gc耗时),意味着task执行用户代码的内存不够用,那么同样建议调低这个参数的值。

3.7 spark.shuffle.memoryFraction

  • 参数说明:该参数用于设置shuffle过程中一个task拉取到上个stage的task的输出后,进行聚合操作时能够使用的Executor内存的比例,默认是0.2。也就是说,Executor默认只有20%的内存用来进行该操作。shuffle操作在进行聚合时,如果发现使用的内存超出了这个20%的限制,那么多余的数据就会溢写到磁盘文件中去,此时就会极大地降低性能。
  • 参数调优建议:如果Spark作业中的RDD持久化操作较少,shuffle操作较多时,建议降低持久化操作的内存占比,提高shuffle操作的内存占比比例,避免shuffle过程中数据过多时内存不够用,必须溢写到磁盘上,降低了性能。此外,如果发现作业由于频繁的gc导致运行缓慢,意味着task执行用户代码的内存不够用,那么同样建议调低这个参数的值。

参考文献:https://www.cnblogs.com/qingyunzong/p/8946637.html

转载于:https://www.cnblogs.com/parent-absent-son/p/10035221.html

相关文章:

linux进程间通信:popen函数通过管道与shell通信

函数描述 FILE *popen(const char* command,const char* type) 该函数的执行过程如下: a. 调用pipe创建一个管道,并fork创建一个子进程来执行shell,shell会创建一个子进程来执行commad b. 将父进程的输入输出重定向到管道,建立一个单向的数据…

新的小游戏发布啦。Pop Jungle

丛林爱消除是一款画面清新,效果绚丽的消除类休闲游戏。你只需要选中尽可能多的图块,并消除它们就可以得到高分,并有无限多的关卡等待你去征服。一旦你开始玩儿你将无法停止下来,如果你还是消除星星的粉丝,那你更加不能…

mysql thread safe_Windows环境下完全手工配置Apache、MySQL和PHP(Thread Safe)

happydagui:现在LAMP(Linux、Apache、MySQL、PHP/Perl/Python的简称)已经很流行了。在Windows下也有类似的,比如 WAMP(Apache, MySQL, PHP on Windows)。这篇文章主要是介绍如何在Windows环境下完全手工配置Apache、MySQL和PHP,都是解压后直接…

点滴积累【C#】---检验编号在本表中自动生成,与其他表无关

检验编号在本表中自动生成,与其他表无关 效果: 描述:在本表中自动生成编号,与其他表无关。 调用: 1 protected void Page_Load(object sender, EventArgs e)2 {3 Response.Expires -1;4 …

Alpha冲刺(9/10)

团队信息 队名:爸爸饿了组长博客:here作业博客:here组员情况 组员1(组长):王彬 过去两天完成了哪些任务 学习jQuery的AJAX部分的基础知识,对web端如何异步获取服务器信息有了初步认识接下来的计划 & 还…

linux进程通信:pipe实现进程同步

文章目录通过管道同步进程实现代码管道缓冲区设置缓冲区大小总结 :pipe的特点通过管道同步进程 管道自带同步互斥机制: 管道的内核实现:fs/pipe.c ,主要通过内核的锁以及等待队列等机制实现 管道的write操作会阻塞进程 当内存缓冲…

(转)MySQL联表查询

资料源于网络 一.内联结、外联结、左联结、右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结。2.外联结:分为外左联结和…

极小连通子图和极大连通子图_强连通分量与拓扑排序

前言由于GacUI里面开始多处用上拓扑排序,我决定把之前瞎JB搞出来的算法换掉,换成个正式的。之前我自己弄了个写起来很简单的算法,然后每一处需要用到的地方我就重新做一遍。当然这样肯定也是不行的,我觉得也差不多积累到重构的临界…

INTERVAL数据类型-007学习笔记

http://baggio785.itpub.net/post/31233/286119 INTERVAL数据类型用来存储两个时间戳之间的时间间隔。 可以指定years and months,或者days,hours,minuts,seconds之间的间隔。本文为oracle的学习笔记,结合实例介绍INTERVAL数据类型。 INTERVAL数据类型用…

scrapy模拟用户登录

scrapy框架编写模拟用户登录的三种方式: 方式一:携带cookie登录,携带cookie一般请求的url为登录后的页面,获取cookie信息应在登录后的页面获取,cookie参数应转成字典形式 # -*- coding: utf-8 -*- import re import sc…

linux 系统调用 open函数使用

函数介绍 本文仅仅将open系统调用的使用简单总结一下&#xff0c;关于其实现原理大批的大佬分享可以自行学习。open系统调用主要用于打开或者创建一个文件&#xff0c;并返回文件描述符。 头文件 #include <fcntl.h>函数名称 a. int open(const char *pathname, int fl…

配置zendframework开始工作(加入环境变量)

首先需要把把两个路径加入到环境变量中 1、我用的php环境是xampp&#xff0c;安装在di盘&#xff0c;我要把d:/xampp/php/这个路径加入到环境变量 2、下载zendframework&#xff08;我用的版本是1.&#xff09;,把安装包中的bin目录加入到环境变量 3、关于设置php/php.ini中设置…

mysql计算两gps坐标的距离_mysql 计算两坐标间的距离

mysql 5.6.1 加入了空间数据支持功能&#xff0c;新增了st_*相关函数&#xff0c;可以非常方便的计算两个地理坐标点的距离了。如下例子&#xff1a;按我的坐标计算周边坐标的距离并由近到远排序select name,st_distance(point(113.327955,23.129717),point)*111195 as distanc…

(转)mxArray数据类型

1 、数据类型mxArray的操作 在上节的Matlab引擎函数中&#xff0c;所有与变量有关的数据类型都是mxArray类型。数据结构mxArray以及大量的mx开头的函数&#xff0c;广泛用于Matlab 引擎程序和Matlab C数学库中。mxArray是一种很复杂的数据结构&#xff0c;与Matlab中的array相对…

Bootstrap笔记(记录不会的知识)

head&#xff1a; <link rel"stylesheet" href"bootstrap.min.css" /> 引入bootstrap.min.css文件 <meta name"viewport" content"widthdevice-width,initial-scale1" /> content"widthdevice-width&#xff1a;设为…

linux 系统调用 read,write和lseek 使用

read系统调用 头文件 #include <unistd.h>函数使用 ssize_t read(int fd, void *buf, size_t count) read 函数会从文件描述符fd中读取指定的count长度的内容&#xff0c;并且将读到的结果放入到buf缓冲区中返回值 count 读取成功&#xff0c;则会返回读到的字节数 小于…

简单有趣的matlab小程序_超实用有趣的五个小程序推荐

大家好&#xff0c;我是小胖。废话不多说&#xff0c;进入正题。1.一周CP共读有趣的灵魂总会相遇。一个极简的社交小程序。通过选择自己喜欢的一本书&#xff0c;匹配到那个跟自己有着一样有趣灵魂的TA。选择好要阅读哪本书之后&#xff0c;填写下资料&#xff0c;就能在看一本…

一些linux下的性能监测工具

1.gprof http://blog.csdn.net/stanjiang2010/article/details/5655143 2.系统性能调优 http://www.ibm.com/developerworks/cn/linux/l-time/part2/index.html?cadrs perf http://www.ibm.com/developerworks/cn/linux/l-cn-perf1/ oprofile http://www.ibm.com/developerwor…

uva 10183 How many Fibs?

数学题&#xff1a; 给你一个区间[a,b]在该区间内有多少个费波那列数&#xff08;包括a&#xff0c;b&#xff09;&#xff0c;数据规模达到10^100。 这题的原理很简单&#xff0c;基本没什么算法&#xff0c;其实更偏重于编程能力&#xff0c;需要用到高精度。另外找区间的地方…

2018/11/29 一个64位操作系统的设计与实现 02 (安装nasm)

操作系统: Centos7 在nasm官网上的到通过yum安装nasm的方法 首先在/etc/yum.repos.d/目录下 新建一个名为nasm.repo的文件, 在这么文件中写入内容如下 : [nasm] nameThe Netwide Assembler baseurlhttp://www.nasm.us/pub/nasm/stable/linux/ enabled1 gpgcheck0[nasm-testing]…

a-awk 计算数值最大,最小,平均值并保留指定位数

awk 计算最大值 echo -e "1\n2\n3\n10\n9\n5\n11\n"|awk BEGIN {max 0} {if ($1>max) max$1 } END {print "Max", max} 输出为&#xff1a;Max 11 或者可以使用sort命令更为便捷&#xff1a; cho -e "1\n2\n3\n10\n9\n5\n11\n"|sort -n |tai…

第18章:MYSQL分区

第18章&#xff1a;分区 目录 18.1. MySQL中的分区概述18.2. 分区类型18.2.1. RANGE分区18.2.2. LIST分区18.2.3. HASH分区18.2.4. KEY分区18.2.5. 子分区18.2.6. MySQL分区处理NULL值的方式18.3. 分区管理18.3.1. RANGE和LIST分区的管理18.3.2. HASH和KEY分区的管理18.3.3. 分…

mysql属性配置提高查询_MYSQL性能优化-安装时优化参数配置提高服务性能

MYSQL性能优化一直是个头痛的问题&#xff0c;目前大多都是直接把页面html静态页面或直接使用了缓存技术&#xff0c;下面我就mysql本身的性能优化来分享一下。安装时优化参数配置提高服务性能在Linux下安装Mysql采用默认配置安装的Mysql却未必是工作在最佳性能状态的&#xff…

c++引用的自我见解

2019独角兽企业重金招聘Python工程师标准>>> 刚开始学习c 学完指针后&#xff0c;其细节比较好明白&#xff0c;但学到引用了以后&#xff0c;只知其表却不知其底层的实现机制&#xff0c;虽然知道引用是别名、声明必须同时初始化等等&#xff0c;但这只是概念性的东…

c# yield关键字原理

https://www.cnblogs.com/blueberryzzz/p/8678700.html c# yield关键字原理详解 1.yield实现的功能yield return&#xff1a;先看下面的代码&#xff0c;通过yield return实现了类似用foreach遍历数组的功能&#xff0c;说明yield return也是用来实现迭代器的功能的。 using st…

linux进程间通信:命名管道FIFO

文章目录FIF&#xff2f; 通信特点系统调用接口应用拥有亲缘关系之间的进程通信非亲缘关系进程之间的通信总结FIF&#xff2f; 通信特点 FIFO文件有文件名 可以像普通文件一样存储在文件系统之中可以像普通文件一样使用open/write读写和pipe文件一样属于流式文件&#xff0c;不…

mysql 账户管理_如何用MySQL 命令来实现账户管理

今天我们要学习的是如何用MySQL 命令的方式来对账号进行管理&#xff0c;我们大家都知道在实际应用中MySQL 命令可以完成多种任务&#xff0c;以下的文章主要是对用MySQL 命令的方式来对账号进行管理的具体内容介绍。手册上说 “GRANT语句允许系统管理员创建MySQL用户账户&…

Can't connect to MySQL server on '127.0.0.1' (10061) (code 2003)解决方法

先验证一下MySQL的服务是否开启&#xff0c;到计算机->管理->服务和应用程序->服务 如果服务已开启&#xff0c;就检查一下C:\WINDOWS\system32\drivers\etc目录下的hosts文件&#xff0c; 是否存在这一下&#xff0c;不存在添加。 最后在mysql的配置文件my.ini中[mys…

学习MongoDB (1) :配置安装

为什么80%的码农都做不了架构师&#xff1f;>>> MongoDB是一种强大、灵活、可扩展的数据存储方式。它扩展了关系型数据库的众多有用的功能&#xff0c;如辅助索引、范围查询、排序。 最近开始在Windows 32位平台下研究MongoDB的使用&#xff0c;为了方便&#xff…

跨域策略文件crossdomain.xml文件

使用crossdomain.xml让Flash可以跨域传输数据 一、crossdomain.xml文件的作用 跨域&#xff0c;顾名思义就是需要的资源不在自己的域服务器上&#xff0c;需要访问其他域服务器。跨域策略文件是一个xml文档文件&#xff0c;主要是为web客户端(如Adobe Flash Player等)设置跨…