1.JobTracker能否决定给当前的TaskTracker节点分配一个Job的具体的哪一个任务?
2.什么是map本地任务?
3.nonRunningMapCache的作用是什么?
4.从TaskTracker节点上分配挂载的本地任务时,如果以前发生过该TaskTracker节点执行某一Map任务失败了的情况,则应将该Map任务该如何处理?

 
分享到: 

QQ好友和群
腾讯微博
QQ空间

收藏
转播
分享
淘帖
支持
反对

欢迎加入about云群371358502、39327136,云计算爱好者群,亦可关注about云腾讯认证空间||关注本站微信
 

回复

使用道具
举报

   

681

主题

1201

帖子

6384

积分

超级版主

积分
6384


沙发

 

 楼主|
发表于 2014-4-6 23:51:53
|
只看该作者
 


所周知,JobTracker节点使用配置的任务调度器TaskScheduler来为某一个具体的TaskTracker节点分配任务,同时这个任务调
度器只能决定给该TaskTracker节点分配哪一个Job或者那些Job的任务以及分配多少个任务,但是它却不能决定给当前的TaskTracker
节点分配一个Job的具体的哪一个任务。

另外,针对一个具体的TaskTracker节点而言,任何一个作业都可以判断它的那些Map任务相对于该TaskTracker节点来说属于本地任务,那些Map任务是属于非本地任务的,当然,对于Reduce任务来说,是没有本地任务与非本地任务这一说法的。

因此,具体来讲就是,当任务调度器决定为一个TaskTracker节点分配一个Job的本地任务时,它会调用该JobInProgress对象的
obtainNewLocalMapTask()方法,分配一个非本地任务时,它会调用对应的obtainNewNonLocalMapTask()方
法,那么以这个TaskTracker节点在集群中的物理位置为参考,这个Job可能有多个本地任务和多个非本地任务,至于为该TaskTracker节
点分配哪一个本地或者非本地任务就由JobInProgress来决定了;当任务调度器为TaskTracker节点分配一个Job的Reduce任务
时,就会调用该Job对应的JobInProgress对象的obtainNewReduceTask()方法。至于JobInProgress对象究竟
是如何分配一个本地或非本地Map任务、Reduce任务的,那将是本文接下来要详细讲述的重点了。

1.分配作业的Map任务


 
   作业的Map任务之所以有本地和非本地之分,主要是因为该Map任务的输入数据和执行该Map任务的TaskTracker节点在集群中的位置有可
能同。本地与非本地Map任务是相对于执行或将要执行该任务的TaskTracker节点来说的,当任务调度器决定为一个TaskTracker节点分配
某一个Job的一个本地Map任务时,它(JobInProgress)会查找这个Job中的那些Map任务的输入数据合该TaskTracker节点在
同一台PC或机架上,那么这些Map任务对于TaskTracker节点来说就是本地任务了。这里要值得一提的是,在作业初始化的时候,就为每一个Map
任务做了一个本地化的预分配工作,即根据Map任务的输入数据的物理位置,将该Map任务挂载到对应的物理节点上,该过程的源代码为:

  1. private Map<Node, List<TaskInProgress>> createCache(JobClient.RawSplit[] splits, int maxLevel) {
  2. Map<Node, List<TaskInProgress>> cache = new IdentityHashMap<Node, List<TaskInProgress>>(maxLevel);
  3. for (int i = 0; i < splits.length; i++) {
  4. String[] splitLocations = splits[i].getLocations();//获取该数据切片坐在的物理位置(多个副本)
  5. if (splitLocations.length == 0) {
  6. nonLocalMaps.add(maps[i]);
  7. continue;
  8. }
  9. //针对每一个副本的物理位置
  10. for(String host: splitLocations) {
  11. //解析副本在集群中的哪一个节点上
  12. Node node = jobtracker.resolveAndAddToTopology(host);
  13. LOG.info("tip:" + maps[i].getTIPId() + " has split on node:" + node);
  14. for (int j = 0; j < maxLevel; j++) {
  15. List<TaskInProgress> hostMaps = cache.get(node);
  16. if (hostMaps == null) {
  17. hostMaps = new ArrayList<TaskInProgress>();
  18. cache.put(node, hostMaps);
  19. hostMaps.add(maps[i]);//将Map任务挂载到该节点上
  20. }
  21. //去重,避免一个节点挂载了两个相同的Map任务
  22. if (hostMaps.get(hostMaps.size() - 1) != maps[i]) {
  23. hostMaps.add(maps[i]);
  24. }
  25. node = node.getParent();//获取节点的父节点(由于maxLevel的值是2,所以父节点就是rack节点)
  26. }
  27. }
  28. }
  29. return cache;
  30. }

复制代码

通过这样的一个预处理过程,最终Node与Map任务之间的映射关系被保存在它的一个属性nonRunningMapCache中了。当
JobInProgress为一个TaskTracker节点分配一个本地Map任务时,它可以只需要解析该TaskTracker节点在集群中的哪一个
节点node上,根据该node就可以从nonRunningMapCache中获取一个Map任务,该Map任务相对于当前这个TaskTracker
来说就是本地任务了;当JobInProgress为一个TaskTracker节点分配一个非本地Map任务时,它可以获取集群中所有的rack节点
(除它自己所在的rack外),通过这些rack节点node,就可以从nonRunningMapCache中获取一个Map任务,该Map任务相对于
当前这个TaskTracker来说就是非本地任务了。

根据上面的源代码可以看出,所谓的本地任务之分就是由maxLevel来确定的,即Map任务的输入数据与TaskTracker节点在集群中的物理距
离,在目前的版本中(Hadoop-0.20.2.0),maxLevel的默认值是2,也可由JobTracker节点的配置文件来设置,对应的配置项
为:mapred.task.cache.levels。另外,从上面的源代码可以看出,这个预处理过程也明确地定义了非本地Map任务,即map操作的
输入数据的位置为null的Map任务,这并不代表说该Map任务没有输入数据。因为,Hadoop为用户提供了自定义数据切片的API(用户自己实现
InputSplit),这里的RawSplit并没有直接保存map操作所需的输入数据的位置信息,而是对真正的InputSplit进行了封装,这告
诉我们两个很重要的情况,

一:用户在自定义Map任务的InputSplit时,应考虑这个Map任务是否可以作为某些TaskTracker节点的本地任务(比如某一个Map任务的输入数据在跨越多个节点,那么这个Map任务永远也不可能是本地任务);

二:Map任务的InputSplit实现可以为map操作带入少量的输入数据(例如,某一个Map任务需要两个输入数据,一个数据很大,另一个数据很
小,只有几百或上千Bytes,那么,用户就可以自定义一个InputSplit来保存这个小数据,很明显,用HDFS保存这样小的数据根本不划算)。这
个非本地Map任务保存在nonLocalMaps属性中。

1.1 分配本地Map任务

JobInProgress给某一个TaskTracker节点分配一个本地Map任务的操作比较的简单,不过,这其中有一个异常情况,就是当这个
TaskTracker节点无法被解析成集群中的一个Node时,那么,本次的本地Map任务分配会被当做一次分配非本地Map任务来操作。这个过程的源
代码如下:

  1. public synchronized Task obtainNewLocalMapTask(TaskTrackerStatus tts,int clusterSize, int numUniqueHosts) throws IOException {
  2. if (!tasksInited.get()) {
  3. return null;
  4. }
  5. //为当前的计算节点获取一个本地map任务
  6. int target = findNewMapTask(tts, clusterSize, numUniqueHosts, maxLevel, status.mapProgress());
  7. if (target == -1) {
  8. return null;
  9. }
  10. Task result = maps[target].getTaskToRun(tts.getTrackerName());
  11. if (result != null) {
  12. addRunningTaskToTIP(maps[target], result.getTaskID(), tts, true);
  13. }
  14. return result;
  15. }

复制代码

  1. /**
  2. * 为当前的计算节点从作业的map任务集中选取一个合适的任务;
  3. * 参数maxCacheLevel决定了当前分配的是本地任务还是非本地任务
  4. */
  5. private synchronized int findNewMapTask(final TaskTrackerStatus
    tts, final int clusterSize, final int numUniqueHosts, final int
    maxCacheLevel, final double avgProgress) {
  6. ...
  7. Node node = jobtracker.getNode(tts.getHost());  //根据当前计算节点的主机/IP来获取其在集群拓扑结构中对应的位置节点
  8. //
  9. // I) Non-running TIP :
  10. // 1. check from local node to the root [bottom up cache lookup]
  11. //    i.e if the cache is available and the host has been resolved
  12. //    (node!=null)
  13. if (node != null) {
  14. Node key = node;    //当前待分配的map任务的输入数据所在的节点
  15. int level = 0;
  16. // maxCacheLevel might be greater than this.maxLevel if findNewMapTask is
  17. // called to schedule any task (local, rack-local, off-switch or speculative)
  18. // tasks or it might be NON_LOCAL_CACHE_LEVEL (i.e. -1) if findNewMapTask is
  19. //  (i.e. -1) if findNewMapTask is to only schedule off-switch/speculative
  20. // tasks
  21. int maxLevelToSchedule = Math.min(maxCacheLevel, maxLevel);
  22. for (level = 0;level < maxLevelToSchedule; ++level) {
  23. List <TaskInProgress> cacheForLevel = nonRunningMapCache.get(key);    //获取节点key上还未分配的map任务
  24. if (cacheForLevel != null) {
  25. tip = findTaskFromList(cacheForLevel, tts, numUniqueHosts,level == 0);   //从一个map任务集中为当前的计算节点找到一个合适的任务
  26. if (tip != null) {
  27. // Add to running cache
  28. scheduleMap(tip);
  29. // remove the cache if its empty
  30. if (cacheForLevel.size() == 0) {
  31. nonRunningMapCache.remove(key);
  32. }
  33. return tip.getIdWithinJob();
  34. }
  35. }
  36. key = key.getParent();
  37. }
  38. // Check if we need to only schedule a local task (node-local/rack-local)
  39. if (level == maxCacheLevel) {
  40. return -1;
  41. }
  42. }
  43. ...
  44. }

复制代码

还有一个值得注意的问题就是,如果该TaskTracker节点所在的Node上有Map任务时,当从该Node上分配挂载的本地任务时,如果以前发生过
该TaskTracker节点执行某一Map任务失败了的情况,则应将该Map任务从Node上删除,同时,对于无法执行或正在执行的Map任务也应该从
Node上删除,对应的源码为:

  1. private synchronized
    TaskInProgress findTaskFromList(Collection<TaskInProgress> tips,
    TaskTrackerStatus ttStatus, int numUniqueHosts, boolean removeFailedTip)
    {
  2. Iterator<TaskInProgress> iter = tips.iterator();
  3. while (iter.hasNext()) {
  4. TaskInProgress tip = iter.next();
  5. // Select a tip if
  6. //   1. runnable   : still needs to be run and is not completed
  7. //   2. ~running   : no other node is running it
  8. //   3. earlier attempt failed : has not failed on this host
  9. //                               and has failed on all the other hosts
  10. // A TIP is removed from the list if
  11. // (1) this tip is scheduled
  12. // (2) if the passed list is a level 0 (host) cache
  13. // (3) when the TIP is non-schedulable (running, killed, complete)
  14. if (tip.isRunnable() && !tip.isRunning()) {
  15. // check if the tip has failed on this host
  16. if (!tip.hasFailedOnMachine(ttStatus.getHost()) || tip.getNumberOfFailedMachines() >= numUniqueHosts) {
  17. // check if the tip has failed on all the nodes
  18. iter.remove();
  19. return tip;
  20. }
  21. else if (removeFailedTip) {
  22. // the case where we want to remove a failed tip from the host cache
  23. // point#3 in the TIP removal logic above
  24. iter.remove();
  25. }
  26. } else {
  27. // see point#3 in the comment above for TIP removal logic
  28. iter.remove();
  29. }
  30. }
  31. return null;
  32. }

复制代码

1.2 分配非本地Map任务

JobInProgress为某一个TaskTracker节点分配一个非本地Map任务相对于分配一个本地任务来说要复杂的多,它首先会先从
nonRunningMapCache中选择一个非本地任务,如果没有找到再从nonLocalMaps中选择一个任务,如果还没有找到,则判断这个作业
是否设置了hasSpeculativeMaps,如果没有设置,则不再为该TaskTracker节点分配非本地Map任务了;如果设置了,则从正在被
其它TaskTracker节点执行的本地或非本地Map任务中选一个,不过这是有优先顺序的,首先从正在运行的runningMapCache中寻找一
个本地Map任务,如果没有找到再从runningMapCache中寻找一个非本地Map任务,最后再从nonLocalRunningMaps中寻找
一个非本地Map任务,此时还没有找到的话,就不再为该TaskTracker节点分配Map任务了。这个过程的源代码如下:

  1. public synchronized Task obtainNewNonLocalMapTask(TaskTrackerStatus tts, int clusterSize, int numUniqueHosts)
  2. throws IOException {
  3. if (!tasksInited.get()) {
  4. return null;
  5. }
  6. int target = findNewMapTask(tts, clusterSize, numUniqueHosts, NON_LOCAL_CACHE_LEVEL, status.mapProgress());
  7. if (target == -1) {
  8. return null;
  9. }
  10. Task result = maps[target].getTaskToRun(tts.getTrackerName());
  11. if (result != null) {
  12. addRunningTaskToTIP(maps[target], result.getTaskID(), tts, true);
  13. }
  14. return result;
  15. }
  16. private synchronized int findNewMapTask(final TaskTrackerStatus
    tts, final int clusterSize, final int numUniqueHosts, final int
    maxCacheLevel, final double avgProgress) {
  17. ...
  18. Collection<Node> nodesAtMaxLevel = jobtracker.getNodesAtMaxLevel();
  19. // get the node parent at max level
  20. Node nodeParentAtMaxLevel = (node == null) ? null : JobTracker.getParentNode(node, maxLevel - 1);
  21. for (Node parent : nodesAtMaxLevel) {
  22. // skip the parent that has already been scanned
  23. if (parent == nodeParentAtMaxLevel) {
  24. continue;
  25. }
  26. List<TaskInProgress> cache = nonRunningMapCache.get(parent);
  27. if (cache != null) {
  28. tip = findTaskFromList(cache, tts, numUniqueHosts, false);
  29. if (tip != null) {
  30. // Add to the running cache
  31. scheduleMap(tip);
  32. // remove the cache if empty
  33. if (cache.size() == 0) {
  34. nonRunningMapCache.remove(parent);
  35. }
  36. LOG.info("Choosing a non-local task " + tip.getTIPId());
  37. return tip.getIdWithinJob();
  38. }
  39. }
  40. }
  41. // 3. Search non-local tips for a new task
  42. tip = findTaskFromList(nonLocalMaps, tts, numUniqueHosts, false);
  43. if (tip != null) {
  44. // Add to the running list
  45. scheduleMap(tip);
  46. LOG.info("Choosing a non-local task " + tip.getTIPId());
  47. return tip.getIdWithinJob();
  48. }
  49. // II) Running TIP :
  50. if (hasSpeculativeMaps) {
  51. long currentTime = System.currentTimeMillis();
  52. // 1. Check bottom up for speculative tasks from the running cache
  53. if (node != null) {
  54. Node key = node;
  55. for (int level = 0; level < maxLevel; ++level) {
  56. Set<TaskInProgress> cacheForLevel = runningMapCache.get(key);
  57. if (cacheForLevel != null) {
  58. tip = findSpeculativeTask(cacheForLevel, tts, avgProgress, currentTime, level == 0);
  59. if (tip != null) {
  60. if (cacheForLevel.size() == 0) {
  61. runningMapCache.remove(key);
  62. }
  63. return tip.getIdWithinJob();
  64. }
  65. }
  66. key = key.getParent();
  67. }
  68. }
  69. // 2. Check breadth-wise for speculative tasks
  70. for (Node parent : nodesAtMaxLevel) {
  71. // ignore the parent which is already scanned
  72. if (parent == nodeParentAtMaxLevel) {
  73. continue;
  74. }
  75. Set<TaskInProgress> cache = runningMapCache.get(parent);
  76. if (cache != null) {
  77. tip = findSpeculativeTask(cache, tts, avgProgress, currentTime, false);
  78. if (tip != null) {
  79. // remove empty cache entries
  80. if (cache.size() == 0) {
  81. runningMapCache.remove(parent);
  82. }
  83. LOG.info("Choosing a non-local task " + tip.getTIPId() + " for speculation");
  84. return tip.getIdWithinJob();
  85. }
  86. }
  87. }
  88. // 3. Check non-local tips for speculation
  89. tip = findSpeculativeTask(nonLocalRunningMaps, tts, avgProgress, currentTime, false);
  90. if (tip != null) {
  91. LOG.info("Choosing a non-local task " + tip.getTIPId() + " for speculation");
  92. return tip.getIdWithinJob();
  93. }
  94. }
  95. return -1;
  96. }

复制代码

2. 分配作业的Reduce任务


      由于
Reduce任务的输入数据来源于该作业所有的Map任务的输出,而执行Map任务的TaskTracker节点将map的输出保存在自己本地,所以
Reduce任务的输入数据在绝大多数情况下不可能都在某一个TaskTracker节点上,因此对于任何一个TaskTracker节点来说没有本地和
非本地的Reduce任务之分。JobInProgress为某一个TaskTracker节点分配一个Reduce任务的操作就相当的简单了,这个过程
类似于分配非本地Map任务。

它首先直接从nonRunningReduces中寻找一个任务,如果没有找到则在看这个作业设置了hasSpeculativeReduces没有,若
没有则不分配了;若设置了,则从runningReduces中寻找一个正在被其它TaskTracker节点执行的Reduce任务分配给该
TaskTracker节点。该过程对应的源代码如下:

  1. public synchronized Task obtainNewReduceTask(TaskTrackerStatus tts, int clusterSize, int numUniqueHosts) throws IOException {
  2. if (status.getRunState() != JobStatus.RUNNING) {
  3. return null;
  4. }
  5. // Ensure we have sufficient map outputs ready to shuffle before
  6. // scheduling reduces
  7. if (!scheduleReduces()) {
  8. return null;
  9. }
  10. int  target = findNewReduceTask(tts, clusterSize, numUniqueHosts, status.reduceProgress());
  11. if (target == -1) {
  12. return null;
  13. }
  14. Task result = reduces[target].getTaskToRun(tts.getTrackerName());
  15. if (result != null) {
  16. addRunningTaskToTIP(reduces[target], result.getTaskID(), tts, true);
  17. }
  18. return result;
  19. }
  20. private synchronized int findNewReduceTask(TaskTrackerStatus tts, int clusterSize, int numUniqueHosts, double avgProgress) {
  21. if (numReduceTasks == 0) {
  22. return -1;
  23. }
  24. String taskTracker = tts.getTrackerName();
  25. TaskInProgress tip = null;
  26. // Update the last-known clusterSize
  27. this.clusterSize = clusterSize;
  28. if (!shouldRunOnTaskTracker(taskTracker)) {
  29. return -1;
  30. }
  31. long outSize = resourceEstimator.getEstimatedReduceInputSize();
  32. long availSpace = tts.getResourceStatus().getAvailableSpace();
  33. if(availSpace < outSize) {
  34. LOG.warn("No local disk space for reduce task.
    TaskTracker[" + taskTracker + "] has " + availSpace + " bytes free; but
    we expect reduce input to take " + outSize);
  35. return -1; //see if a different TIP might work better.
  36. }
  37. // 1. check for a never-executed reduce tip
  38. // reducers don't have a cache and so pass -1 to explicitly call that out
  39. tip = findTaskFromList(nonRunningReduces, tts, numUniqueHosts, false);
  40. if (tip != null) {
  41. scheduleReduce(tip);
  42. return tip.getIdWithinJob();
  43. }
  44. // 2. check for a reduce tip to be speculated
  45. if (hasSpeculativeReduces) {
  46. tip = findSpeculativeTask(runningReduces, tts, avgProgress, System.currentTimeMillis(), false);
  47. if (tip != null) {
  48. scheduleReduce(tip);
  49. return tip.getIdWithinJob();
  50. }
  51. }
  52. return -1;
  53. }
  54. private synchronized TaskInProgress
    findSpeculativeTask(Collection<TaskInProgress> list,
    TaskTrackerStatus ttStatus, double avgProgress, long currentTime,
    boolean shouldRemove) {
  55. Iterator<TaskInProgress> iter = list.iterator();
  56. while (iter.hasNext()) {
  57. TaskInProgress tip = iter.next();
  58. // should never be true! (since we delete completed/failed tasks)
  59. if (!tip.isRunning()) {
  60. iter.remove();
  61. continue;
  62. }
  63. //当前TaskTracker节点没有运行该任务
  64. if (!tip.hasRunOnMachine(ttStatus.getHost(), ttStatus.getTrackerName())) {
  65. if (tip.hasSpeculativeTask(currentTime, avgProgress)) {
  66. // In case of shared list we don't remove it. Since the TIP failed
  67. // on this tracker can be scheduled on some other tracker.
  68. if (shouldRemove) {
  69. iter.remove(); //this tracker is never going to run it again
  70. }
  71. return tip;
  72. }
  73. } else {
  74. // Check if this tip can be removed from the list.
  75. // If the list is shared then we should not remove.
  76. if (shouldRemove) {
  77. // This tracker will never speculate this tip
  78. iter.remove();
  79. }
  80. }
  81. }
  82. return null;
  83. }

复制代码

在目前的Hadoop版本设计中,作业中任务的调度细节被封装到了JobInProgress中,使得作业调度器TaskScheduler可完全控制的
调度粒度限制在Job级,同时JobInProgress为上层的TaskScheduler实现的任务调度提供API,这样做就大大地降低了用户自行设
计TaskScheduler的门槛,即可以很容易的根据自己的应用场景集中在作业级别上实现合适的调度策略。

分析JobInProgress中Map/Reduce任务分配的更多相关文章

  1. hadoop入门级总结二:Map/Reduce

    在上一篇博客:hadoop入门级总结一:HDFS中,简单的介绍了hadoop分布式文件系统HDFS的整体框架及文件写入读出机制.接下来,简要的总结一下hadoop的另外一大关键技术之一分布式计算框架: ...

  2. MapReduce剖析笔记之五:Map与Reduce任务分配过程

    在上一节分析了TaskTracker和JobTracker之间通过周期的心跳消息获取任务分配结果的过程.中间留了一个问题,就是任务到底是怎么分配的.任务的分配自然是由JobTracker做出来的,具体 ...

  3. Map/Reduce 工作机制分析 --- 作业的执行流程

    前言 从运行我们的 Map/Reduce 程序,到结果的提交,Hadoop 平台其实做了很多事情. 那么 Hadoop 平台到底做了什么事情,让 Map/Reduce 程序可以如此 "轻易& ...

  4. 第九篇:Map/Reduce 工作机制分析 - 作业的执行流程

    前言 从运行我们的 Map/Reduce 程序,到结果的提交,Hadoop 平台其实做了很多事情. 那么 Hadoop 平台到底做了什么事情,让 Map/Reduce 程序可以如此 "轻易& ...

  5. hadoop中map和reduce的数量设置

    hadoop中map和reduce的数量设置,有以下几种方式来设置 一.mapred-default.xml 这个文件包含主要的你的站点定制的Hadoop.尽管文件名以mapred开头,通过它可以控制 ...

  6. MapReduce启动的Map/Reduce子任务简要分析

      对于Hadoop来说,是通过在DataNode中启动Map/Reduce java进程的方式来实现分布式计算处理的,那么就从源码层简要分析一下hadoop中启动Map/Reduce任务的过程.   ...

  7. hadoop中map和reduce的数量设置问题

    转载http://my.oschina.net/Chanthon/blog/150500 map和reduce是hadoop的核心功能,hadoop正是通过多个map和reduce的并行运行来实现任务 ...

  8. 【转】Python 中map、reduce、filter函数

    转自:http://www.blogjava.net/vagasnail/articles/301140.html?opt=admin 介绍下Python 中 map,reduce,和filter 内 ...

  9. 基于python的《Hadoop权威指南》一书中气象数据下载和map reduce化数据处理及其可视化

    文档内容: 1:下载<hadoop权威指南>中的气象数据 2:对下载的气象数据归档整理并读取数据 3:对气象数据进行map reduce进行处理 关键词:<Hadoop权威指南> ...

随机推荐

  1. 关于go语言的环境配置 SDK+path+工作目录

    第一步: 安装Golang的SDK http://golang.org,下载最新的安装包,之后双击安装即可. 安装完成之后,打开终端,输入go.或者go version(查看安装版本)出现如下信息即表 ...

  2. SAP HR模块的基础数据表和增强配置

    信息类型是SAP HR模块数据单元,用于对人员数据的记录和维护,是HR的基础.信息类型按照其创建方式的不同可以分为:人事信息类型.组织信息类型.信息类型数据的维护主要在事物码PA30.PA40.po1 ...

  3. CentOS 7 之前好好的,突然一天启动时黑屏,没有登陆界面了(配置 network-scripts 连网)

    原因: 百度大神说是Gnome(一套纯粹自由的计算机软件,运行在操作系统上,提供图形桌面环境)不行了. 解决方法: 1. 重启系统,ctrl + alt + F2 进入命令行界面. 2. sudo s ...

  4. 飞机找不到,流量哪去了?记一次移动WAP网关导致的问题

    这几天随着客户端一个新版本发布,运维发现CDN的流量猛跌: 话说流量就是金钱,流量就是工资.领导很生气,后果很严重.没什么好说的,赶紧查!一开始怀疑服务端有问题,先受伤的总是我们,当然这也是没错的,因 ...

  5. Solr系列五:solr搜索详解(solr搜索流程介绍、查询语法及解析器详解)

    一.solr搜索流程介绍 1. 前面我们已经学习过Lucene搜索的流程,让我们再来回顾一下 流程说明: 首先获取用户输入的查询串,使用查询解析器QueryParser解析查询串生成查询对象Query ...

  6. e835. 使JTabbedPane中的卡片生效和失效

    By default, all new tabs are enabled, which means the user can select them. A tab can be disabled to ...

  7. MP3帧时长为26ms的来历

  8. HTTP之referer

    安全培训中提到可以通过referer判断安全性,hackbar中也有一个enable referer的选项,则,这个referer到底是个什么角色? (以下是搜集的一些资料整合,链接均放到底部,不再一 ...

  9. jquery ajax 设置全局(常量和变量)

    允许同源(相同域名不同端口)跨域配置: $.ajaxSetup({ xhrFields: { withCredentials: true } }); ajax所有的请求的全局设置: 此处为设置 自定义 ...

  10. Java读写配置文件——Properties类的简要使用笔记

    任何编程语言都有自己的读写配置文件的方法和格式,Java也不例外. 在Java编程语言中读写资源文件最重要的类是Properties,功能大致如下: 1. 读写Properties文件 2. 读写XM ...