1 HDFS均衡操作原理

HDFS默认的块的副本存放策略是在发起请求的客户端存放一个副本,如果这个客户端在集群以外,那就选择一个不是太忙,存储不是太满的节点来存放,第二个副本放在与第一个副本相同的机架但是不同节点上,第三个放在与第二个和第一个副本不同的机架上,原则是尽量避免在相同的机架上放太多的副本。

随着时间的推移,在各个DataNode节点上的数据块会分布的越来越不均衡。如果集群不均衡的程度很严重,会降低Mapreduce的使用性能,导致部分DataNode节点相对而言变得更加繁忙。所以,应该尽量的避免出现这种情况。

HDFS的 Balancer 类,是为了实现HDFS的负载调整而存在的。Balancer类是以一个独立的进程存在的,可以独立的运行和配置。它NameNode节点进行通信,获取各个DataNode节点的负载状况,从而进行调整DataNode上的Block的分布。主要的调整其实就是一个操作,将一个数据块从一个服务器搬迁到另一个服务器上。Balancer会向相关的目标 DataNode 节点  发出一个DataTransferProtocol.OP_REPLACE_BLOCK  消息,接收到这个消息的DataNode节点,会将从源DataNode节点传输来的数据块写入本地,写成功后,通知NameNode,删除源DataNode上的同一个数据块,直到集群达到均衡为止,即每个DataNode的使用率(该节点已使用的空间和空间容量之间的百分比值)和集群的使用率(集群中已使用的空间和集群的空间容量之间的百分比值)非常接近,差距不超过均衡时给定的阈值。

其中,一个块是否可以被移动,要满足三个条件:

(1)正在被移动或者已经被移动的块,不会重复移动

(2)一个块如果在源节点和目标节点上都有其副本,则此块不会被移动;

(3)移动不会减少一个块所在的机架的数目;

可见,由于上述等条件的限制,均衡操作并不能使得HDFS达到真正意义上的均衡,它只能是尽量的减少不均衡。

均衡操作依靠一个均衡操作服务器、NameNode的代理和DataNode来实现,其逻辑流程如下:

其中,

Step1:Rebalance Server从Name Node中获取所有的Data Node情况,即每一个Data Node磁盘使用情况;

Step2: Rebalance Server计算哪些Dataode节点需要将数据移动,哪些Dataode节点可以接受移动的块数据,并且从NameNode中获取需要移动的数据分布情况;

Step3: Rebalance Server计算出来可以将哪一台Dataode节点的block移动到另一台机器中去;

Step4、5、6:需要移动block的Dataode节点将数据移动到目标DataNode节点上去,同时删除自己节点上的block数据;

Step7: Rebalance Server获取到本次数据移动的执行结果,并继续执行这个过程,一直到没有数据可以移动或者HDFS集群以及达到了平衡的标准为止;

在step2中,HDFS会把当前的DataNode节点根据阈值的设定情况划分到四个链表中:

(1)over组:此组中的DataNode的均满足

DataNode_usedSpace_percent  > Cluster_usedSpace_percent + threshold;

(2)above组:此组中的DataNode的均满足

Cluster_usedSpace_percent + threshold > DataNode_ usedSpace _percent  > Cluster_usedSpace_percent;

(3)below组:此组中的DataNode的均满足

Cluster_usedSpace_percent > DataNode_ usedSpace_percent  > Cluster_ usedSpace_percent – threshold;

(4)under组:此组中的DataNode的均满足

Cluster_usedSpace_percent – threshold > DataNode_usedSpace_percent;

用一个示例图表示:

在移动块的时候,会把over组和above组中的块向below组和under组移动,直到均衡状态或者达到均衡退出的条件为止。

总得来说,均衡操作的步骤可以分为4步:

(1)从namenode获取datanode磁盘使用情况;

(2)计算哪些节点需要把哪些数据移动到哪里;

(3)分别移动,完成后删除旧的block信息;

(4)循环执行,直到达到平衡标准;

2 HDFS均衡操作的启动

使用HDFS的balancer命令,可以配置一个Threshold来平衡每一个DataNode磁盘利用率。命令如下:

start-balancer.sh -threshold 8

运行之后,会有Balancer进程出现:

上述命令设置了Threshold为8%,那么执行balancer命令的时候,首先统计所有DataNode的磁盘利用率的均值,然后判断如果某一个DataNode的磁盘利用率超过这个均值Threshold,那么将会把这个DataNode的block转移到磁盘利用率低的DataNode,这对于新节点的加入来说十分有用。Threshold的值为1到100之间,不显示的进行参数设置的话,默认是10。

范围超出之后,会有异常抛出:

java.lang.IllegalArgumentException: Number out of range: threshold = 0.07

at org.apache.hadoop.hdfs.server.balancer.Balancer$Cli.parse(Balancer.java:1535)

at org.apache.hadoop.hdfs.server.balancer.Balancer$Cli.run(Balancer.java:1510)

at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)

at org.apache.hadoop.hdfs.server.balancer.Balancer.main(Balancer.java:1582)

2012-12-19 16:28:33,299 ERROR org.apache.hadoop.hdfs.server.balancer.Balancer: Exiting balancer due an exception

java.lang.IllegalArgumentException: Number out of range: threshold = 110.0

at org.apache.hadoop.hdfs.server.balancer.Balancer$Cli.parse(Balancer.java:1535)

at org.apache.hadoop.hdfs.server.balancer.Balancer$Cli.run(Balancer.java:1510)

at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)

at org.apache.hadoop.hdfs.server.balancer.Balancer.main(Balancer.java:1582)

如果参数值设置的越小,花费的时间就越长。使用此命令时,会反复的从磁盘使用率高的节点上,把块转移到磁盘使用率低的磁盘上,每次移动不超过10G大小,每次移动不超过20分钟。

在做均衡的时候,会对网络带宽有影响,可在配置文件中对均衡操作的带宽做限制:

<property>

<name>dfs.balance.bandwidthPerSec</name>

<value>1048576</value>

<description>

Specifies the maximum bandwidth that each datanode can utilize for the balancing purpose in term of the number of bytes per second.

</description>

</property>

若不设置,则balance操作时,速度默认为1M/S大小。参数重启时生效。不允许在集群中使用多个均衡同时操作。

3 HDFS均衡操作的退出

除了在命令行直接使用stop-balancer.sh脚本来执行退出均衡操作之外,当发生以下几种情况时,当前执行的均衡操作也会退出:

(1)集群已经达到均衡状态;

(2)没有块可以再被移动;

(3)连续五次迭代操作时没有块移动;

(4)和NameNode通信时出现IOException;

(5)另外一个均衡操作启动;

4 实例分析

均衡操作之前DataNode节点块分布情况:

在sbin目录下执行命令./start-balancer.sh -threshold 5

均衡过程中:

开始做均衡操作时,会有如下日志打印出:

2012-12-28 10:08:55,667 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: Using a threshold of 5.0

2012-12-28 10:08:55,668 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: namenodes = [hdfs://goon]

2012-12-28 10:08:55,669 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: p         = Balancer.Parameters[BalancingPolicy.Node, threshold=5.0]

其中会标明对哪些nameservice进行均衡,同时对输入的参数进行说明,默认的策略是BalancingPolicy.Node,表示均衡的对象是DataNode,否则是对块池做均衡。

之后,会计算需要移动的块,移动的字节数,块的源地址和目标地址:

2012-12-28 10:08:57,200 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: 1 over-utilized: [Source[10.28.169.126:50010, utilization=25.807874799394025]]

2012-12-28 10:08:57,200 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: 1 underutilized: [BalancerDatanode[10.28.169.122:50010, utilization=9.395091359283992]]

2012-12-28 10:08:57,201 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: Need to move 2.75 GB to make the cluster balanced.

2012-12-28 10:08:57,202 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: Decided to move 2.46 GB bytes from 10.28.169.126:50010 to 10.28.169.122:50010

2012-12-28 10:08:57,203 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: Will move 2.46 GB in this iteration

此时:

刚开始均衡操作时,其进程所占资源:

同时,可以观察到会有块的移动,从datanode0移动到sdc2和Tdatanode0,在NN会有如下日志(hadoop-hdfs-balancer-Tdatanode0.log):

2012-12-28 10:08:57,724 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: Moving block 365766470964968392 from 10.28.169.126:50010 to 10.28.169.122:50010 through 10.28.169.225:50010 is succeeded.

2012-12-28 10:08:57,724 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: Moving block 7346867188539736438 from 10.28.169.126:50010 to 10.28.169.122:50010 through 10.28.169.225:50010 is succeeded.

2012-12-28 10:08:57,724 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: Moving block -6882244909405313690 from 10.28.169.126:50010 to 10.28.169.122:50010 through 10.28.169.225:50010 is succeeded.

由于在Balancer类中对线程池做了限制,

final static private int MOVER_THREAD_POOL_SIZE = 1000;

所以最多可以有1000个线程并发块移动操作,但是向一个DN进行移动块时,最多5个块并发移动。

由于机器资源的限制,当均衡操作创建的线程数量达到900多的时候,就无法再创建线程,并有如下错误:

2012-12-28 10:19:32,905 WARN org.apache.hadoop.hdfs.server.balancer.Balancer: Dispatcher thread failed

java.lang.OutOfMemoryError: unable to create new native thread

at java.lang.Thread.start0(Native Method)

at java.lang.Thread.start(Thread.java:640)

at java.util.concurrent.ThreadPoolExecutor.addIfUnderCorePoolSize(ThreadPoolExecutor.java:703)

at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:652)

at org.apache.hadoop.hdfs.server.balancer.Balancer$PendingBlockMove.scheduleBlockMove(Balancer.java:402)

at org.apache.hadoop.hdfs.server.balancer.Balancer$PendingBlockMove.access$3500(Balancer.java:236)

at org.apache.hadoop.hdfs.server.balancer.Balancer$Source.dispatchBlocks(Balancer.java:746)

at org.apache.hadoop.hdfs.server.balancer.Balancer$Source.access$2000(Balancer.java:591)

at org.apache.hadoop.hdfs.server.balancer.Balancer$Source$BlockMoveDispatcher.run(Balancer.java:598)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)

at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)

at java.util.concurrent.FutureTask.run(FutureTask.java:138)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

at java.lang.Thread.run(Thread.java:662)

查看均衡操作所产生的线程会被阻塞:

Thread 15688: (state = BLOCKED)

- sun.misc.Unsafe.park(boolean, long) @bci=0 (Interpreted frame)

- java.util.concurrent.locks.LockSupport.park(java.lang.Object) @bci=14, line=156 (Interpreted frame)

- java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await() @bci=42, line=1987 (Interpreted frame)

- java.util.concurrent.LinkedBlockingQueue.take() @bci=29, line=399 (Interpreted frame)

- java.util.concurrent.ThreadPoolExecutor.getTask() @bci=78, line=947 (Interpreted frame)

- java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=18, line=907 (Interpreted frame)

- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)

Thread 15687: (state = BLOCKED)

- sun.misc.Unsafe.park(boolean, long) @bci=0 (Interpreted frame)

- java.util.concurrent.locks.LockSupport.park(java.lang.Object) @bci=14, line=156 (Interpreted frame)

- java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await() @bci=42, line=1987 (Interpreted frame)

- java.util.concurrent.LinkedBlockingQueue.take() @bci=29, line=399 (Interpreted frame)

- java.util.concurrent.ThreadPoolExecutor.getTask() @bci=78, line=947 (Interpreted frame)

- java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=18, line=907 (Interpreted frame)

- java.lang.Thread.run() @bci=11, line=662 (Interpreted frame)

同时,由于无法创建线程,RPC通信也会阻塞,

2012-12-28 10:37:28,710 WARN org.apache.hadoop.io.retry.RetryInvocationHandler: Exception while invoking renewLease of class ClientNamenodeProtocolTranslatorPB. Trying to fail over immediately.

2012-12-28 10:37:28,716 WARN org.apache.hadoop.io.retry.RetryInvocationHandler: Exception while invoking renewLease of class ClientNamenodeProtocolTranslatorPB after 1 fail over attempts. Trying to fail over immediately.

2012-12-28 10:37:28,721 WARN org.apache.hadoop.io.retry.RetryInvocationHandler: Exception while invoking renewLease of class ClientNamenodeProtocolTranslatorPB after 2 fail over attempts. Trying to fail over immediately.

。。。

。。。

2012-12-28 10:37:28,795 WARN org.apache.hadoop.io.retry.RetryInvocationHandler: Exception while invoking renewLease of class ClientNamenodeProtocolTranslatorPB after 14 fail over attempts. Trying to fail over immediately.

2012-12-28 10:37:28,802 WARN org.apache.hadoop.io.retry.RetryInvocationHandler: Exception while invoking class org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.renewLease. Not retrying because failovers (15) exceeded maximum allowed (15)

java.io.IOException: Failed on local exception: java.io.IOException: Couldn’t set up IO streams; Host Details : local host is: “Tdatanode0/10.28.169.126″; destination host is: “sdc1″:9000;

at org.apache.hadoop.net.NetUtils.wrapException(NetUtils.java:760)

at org.apache.hadoop.ipc.Client.call(Client.java:1168)

at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:202)

at $Proxy11.renewLease(Unknown Source)

at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolTranslatorPB.renewLease(ClientNamenodeProtocolTranslatorPB.java:452)

at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)

at java.lang.reflect.Method.invoke(Method.java:597)

at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:164)

at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:83)

at $Proxy12.renewLease(Unknown Source)

at org.apache.hadoop.hdfs.DFSClient.renewLease(DFSClient.java:613)

at org.apache.hadoop.hdfs.LeaseRenewer.renew(LeaseRenewer.java:411)

at org.apache.hadoop.hdfs.LeaseRenewer.run(LeaseRenewer.java:436)

at org.apache.hadoop.hdfs.LeaseRenewer.access$700(LeaseRenewer.java:70)

at org.apache.hadoop.hdfs.LeaseRenewer$1.run(LeaseRenewer.java:297)

at java.lang.Thread.run(Thread.java:662)

Caused by: java.io.IOException: Couldn’t set up IO streams

at org.apache.hadoop.ipc.Client$Connection.setupIOstreams(Client.java:640)

at org.apache.hadoop.ipc.Client$Connection.access$1700(Client.java:220)

at org.apache.hadoop.ipc.Client.getConnection(Client.java:1217)

at org.apache.hadoop.ipc.Client.call(Client.java:1144)

… 15 more

Caused by: java.lang.OutOfMemoryError: unable to create new native thread

at java.lang.Thread.start0(Native Method)

at java.lang.Thread.start(Thread.java:640)

at org.apache.hadoop.ipc.Client$Connection.setupIOstreams(Client.java:633)

… 18 more

对每个NameNode都会尝试两次连接 set up IO streams,周期性的进行连接请求,即NN1连接不成功(尝试连接2次),然后就去尝试连接NN2(若尝试连接2次,不成功,就再去连接NN1),每次尝试连接NN后,都会有15次的更新租约尝试,当然,连接不上NN,租约更新也是失效的。

同时,由于此均衡是在NN上操作的,此NN节点会出现僵死状态(在NN上进行均衡仅为测试用,真正使用时不会在NN上),通过web不能访问,因为操作不能再创建新的线程。并且,如果当前是在active节点上进行的操作,而且在配置文件中配置了允许HA自动切换,那么此时会发生HA自动切换,即当前的standby节点变为active节点。

可以在linux下更改参数进行扩大线程创建的数量:

更改之前:

通过命令ulimit -u 65535临时修改,或者通过修改配置文件永久修改:/etc/security/limits.conf

同时也可以修改栈空间所占的大小,默认是10240字节,可以通过ulimit -s 1024修改为1024字节,减少每个堆栈的使用空间,也可以增加线程的数量。

另外,在均衡过程中,Balancer的内存使用情况如下:

所占内存大概是140M左右。在运行过程中,会产生一些垃圾文件,因为节点硬件的限制,所以必须对缓存进行清理:

若出现socket连接异常,则块移动失败,则会提示:

2012-12-21 13:10:42,915 WARN org.apache.hadoop.hdfs.server.balancer.Balancer: Error moving block -5503762968190078708 from 10.28.169.225:50010 to 10.28.169.122:50010 through 10.28.169.225:50010: Connection reset

均衡之后:

当出现日志:

2012-12-28 12:20:00,430 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /default-rack/10.28.169.122:50010

2012-12-28 12:20:00,431 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /default-rack/10.28.169.225:50010

2012-12-28 12:20:00,431 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /default-rack/10.28.169.126:50010

2012-12-28 12:20:00,431 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: 0 over-utilized: []

2012-12-28 12:20:00,431 INFO org.apache.hadoop.hdfs.server.balancer.Balancer: 0 underutilized: []

均衡操作结束,因为Over组没有DataNode,Under组也没有DataNode,此时:

在均衡操作之前:        clusterAvg1

=集群dfs已使用空间/集群总空间

=(12.7+12.19+4.62)/(49.22+49.22+49.22)

=19.99%

我们在做均衡时所设定的阈值为5,即百分之5,clusterAvg1-5%=14.99%,clusterAvg1+5%=24.99%,而Tdatanode0的空间使用率是25.81%,超过 24.99% ,属于over节点,sdc2的空间使用率是9.4%,低于14.99%,属于under节点,datanode0的空间使用率是24.76%,高于14.99%但是低于24.99%,属于above节点,符合均衡操作的发生条件。

集群的空间平均使用率为:   clusterAvg2

=集群dfs已使用空间/集群总空间

=(12.7+11.46+8.91)/(49.22+49.22+49.22)

=22.41%

我们在做均衡时所设定的阈值为5,即百分之5,clusterAvg2-5%=17.41%,clusterAvg2+5%=27.41%,所有的DN的空间使用率都在17.41%–27.41%中间,说明集群已经达到均衡状态。

转载:http://www.tuicool.com/articles/uaaEve

Apache Hadoop2.0之HDFS均衡操作分析的更多相关文章

  1. 如何编译Apache Hadoop2.6.0源代码

    如何编译Apache Hadoop2.6.0源代码 1.安装CentOS 我使用的是CentOS6.5,下载地址是http://mirror.neu.edu.cn/centos/6.5/isos/x8 ...

  2. 【甘道夫】Win7x64环境下编译Apache Hadoop2.2.0的Eclipse小工具

    目标: 编译Apache Hadoop2.2.0在win7x64环境下的Eclipse插件 环境: win7x64家庭普通版 eclipse-jee-kepler-SR1-win32-x86_64.z ...

  3. [置顶] Hadoop2.2.0中HDFS的高可用性实现原理

    在Hadoop2.0.0之前,NameNode(NN)在HDFS集群中存在单点故障(single point of failure),每一个集群中存在一个NameNode,如果NN所在的机器出现了故障 ...

  4. hadoop之 Hadoop2.2.0中HDFS的高可用性实现原理

    在Hadoop2.0.0之前,NameNode(NN)在HDFS集群中存在单点故障(single point of failure),每一个集群中存在一个NameNode,如果NN所在的机器出现了故障 ...

  5. hadoop2.0的datanode数据存储文件夹策略的多个副本

    在hadoop2.0在,datanode数据存储盘选择策略有两种方式复制: 首先是要遵循hadoop1.0磁盘文件夹投票,实现类:RoundRobinVolumeChoosingPolicy.java ...

  6. hadoop2.0的数据副本存放策略

    在hadoop2.0中,datanode数据副本存放磁盘选择策略有两种方式: 第一种是沿用hadoop1.0的磁盘目录轮询方式,实现类:RoundRobinVolumeChoosingPolicy.j ...

  7. Apache Hadoop2.x 边安装边入门

    完整PDF版本:<Apache Hadoop2.x边安装边入门> 目录 第一部分:Linux环境安装 第一步.配置Vmware NAT网络 一. Vmware网络模式介绍 二. NAT模式 ...

  8. hadoop入门(3)——hadoop2.0理论基础:安装部署方法

    一.hadoop2.0安装部署流程         1.自动安装部署:Ambari.Minos(小米).Cloudera Manager(收费)         2.使用RPM包安装部署:Apache ...

  9. hadoop2.0初识1.3

    1.配置分布式hadoop 1.1 准备三台测试机(虚拟机就可以) 1.1.1 将life-hadoop虚拟机克隆2个分别为life-hadoop02和life-hadoop03 1.1.2 查看ip ...

随机推荐

  1. MySQL源码 数据结构hash

    MySQL源码自定义了hash表,因为hash表具有O(1)的查询效率,所以,源码中大量使用了hash结构.下面就来看下hash表的定义: [源代码文件include/hash.h mysys/has ...

  2. bzoj3238

    都LCP了很显然是要用到后缀数组的 显然前面的那个东西是可以直接算出来的 关键在于LCP的和怎么快速的计算 不难想到穷举height[i],然后判断这个height[i]可能成为多少对后缀的LCP 考 ...

  3. App架构经验总结(转)

    原文链接: http://keeganlee.me/post/architecture/20160303 架构因人而异,不同的架构师大多会有不同的看法:架构也因项目而异,不同的项目需求不同,相应的架构 ...

  4. JIRA Cannot Start Due to 'unable to clean the cache directory: /opt/jira/plugins/.osgi-plugins/felix'

    Symptoms After restarting JIRA, the following error appeared: JIRA Startup Failed You cannot access ...

  5. 我泡在GitHub上的177天 by Ryan Seys

    我泡在GitHub上的177天   这是一个关于我如何连续177天(将近半年)泡在GitHub上不间断地贡献代码的故事.我会谈到我为什么要这么做,以及为什么你也应该效仿,或者至少做点类似的事情.这是一 ...

  6. FusionCharts参数说明-----3D饼图属性(Pie3D.swf )

    animation 是否显示加载图表时的动画 palette 内置的图表样式,共5个 paletteColors 自定义图表元素颜色(为多个,如过过少会重复) showAboutMenuItem 右键 ...

  7. SQL Server 字段状态判断语句

    selct newName=case when  条件 then '否' else '是' end from tableName

  8. the private key for is not installed on this mac

    the private key for is not installed on this mac 如果提交 时出现这个问题, 有可能是 keychain重复了, 1:要去keychain中把旧的删除, ...

  9. (转载)顺序栈c++实现

    (转载)http://myswirl.blog.163.com/blog/static/51318642200882310239324/ SqStack.h********************** ...

  10. Rank of Tetris HDU--1881

    Rank of Tetris Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...