精华内容
下载资源
问答
  • 高校网络信息资源的有效开发和利用,艾世尧,,通过对网络信息资源开发利用现状和问题的分析,提出开发利用网络信息资源的原则、构想,以及图书馆自身软、硬件环境的建设。
  • 当发生 System.exit(int status) 时,希望在系统退出前,执行一点任务来做一些资源方面的回收操作,ShutdownHook 可以达到这个目的,它利用 hook 的思路来实现,有些时候也把它叫作“钩子”。 假如在系统中通过 ...

    目录

    ShutdownHook执行原理

    ShutdownHook适用场景


    参考书籍:《Java特种兵(上册)》 

    当发生 System.exit(int status) 时,希望在系统退出前,执行一点任务来做一些资源方面的回收操作,ShutdownHook 可以达到这个目的,它利用 hook 的思路来实现,有些时候也把它叫作“钩子”。

    假如在系统中通过 Runtime.getRuntime().exec(String command) 或 new ProcessBuilder(List<String> command) 启动了子进程(Process),这个子进程一直在运行中,在当前进程退出时,子进程未必会退出,但此时业务上希望将它退出,就可以利用 ShutdownHook 。例如下面这个测试样例: 

    public class ShutdownHookTest {
    
    	public static void main(String[] args) {
    		Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
    			public void run() {
    				System.out.println("执行ShutdownHook钩子操作,释放系统资源...");
    			}
    		}));
    		Runtime.getRuntime().removeShutdownHook(new Thread());
    		System.exit(1);
    		System.out.println("主进程结束...");
    	}
    }
    

    执行结果:

    主进程结束...
    执行ShutdownHook钩子操作,释放系统资源...

    注意:传入参数是通过 new Thread() 创建的线程对象,在Java进程调用 exit() 时,会调用该线程对象的 start()方法将其运行起来,所以不要手工先启动了。另外,这种回调线程就不要设定为死循环程序,否则就无法退出了。

    ShutdownHook执行原理

    java.lang包下有一个Shutdown 类,提供了一个 Runnable[] hooks 数组,数组的长度为10,也就是最多定义10个hook(这与程序写入多少个线程回调没有关系),提供 add() 方法来注册新的 hook 对象。 

        // The system shutdown hooks are registered with a predefined slot.
        // The list of shutdown hooks is as follows:
        // (0) Console restore hook
        // (1) Application hooks
        // (2) DeleteOnExit hook
        private static final int MAX_SYSTEM_HOOKS = 10;
        private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
        /* Add a new shutdown hook.  Checks the shutdown state and the hook itself,
         * but does not do any security checks.
         */
        static void add(int slot, Runnable hook) {
            synchronized (lock) {
                if (state > RUNNING)
                    throw new IllegalStateException("Shutdown in progress");
    
                if (hooks[slot] != null)
                    throw new InternalError("Shutdown hook at slot " + slot + " already registered");
    
                hooks[slot] = hook;
            }
        }
        

    在java.lang.ApplicationShutdownHooks 的static 匿名块中,通过 add() 方法注册了一个hook ,在 run() 方法内部运行内部的静态方法 runHooks() ,它内部用一个 IdentityHashMap 来存放 hook 信息,可以通过 add() 方法来添加,而程序中定义的回调线程都放在了这里,它自身用hook 的形式存在于 hooks 列表当中。 

    package java.lang;
    
    import java.util.*;
    
    /*
     * Class to track and run user level shutdown hooks registered through
     * <tt>{@link Runtime#addShutdownHook Runtime.addShutdownHook}</tt>.
     *
     * @see java.lang.Runtime#addShutdownHook
     * @see java.lang.Runtime#removeShutdownHook
     */
    
    class ApplicationShutdownHooks {
        static {
            Shutdown.add(1 /* shutdown hook invocation order */,
                new Runnable() {
                    public void run() {
                        runHooks();
                    }
                });
        }
    
        /* The set of registered hooks */
        private static IdentityHashMap<Thread, Thread> hooks = new IdentityHashMap<Thread, Thread>();
    
        private void ApplicationShutdownHooks() {}
    
        /* Add a new shutdown hook.  Checks the shutdown state and the hook itself,
         * but does not do any security checks.
         */
        static synchronized void add(Thread hook) {
    	if(hooks == null)
    	    throw new IllegalStateException("Shutdown in progress");
    
    	if (hook.isAlive())
    	    throw new IllegalArgumentException("Hook already running");
    
    	if (hooks.containsKey(hook))
    	    throw new IllegalArgumentException("Hook previously registered");
    
            hooks.put(hook, hook);
        }
    
        /* Remove a previously-registered hook.  Like the add method, this method
         * does not do any security checks.
         */
        static synchronized boolean remove(Thread hook) {
    	if(hooks == null)
    	    throw new IllegalStateException("Shutdown in progress");
    
    	if (hook == null) 
    	    throw new NullPointerException();
    
    	return hooks.remove(hook) != null;
        }
    
        /* Iterates over all application hooks creating a new thread for each
         * to run in. Hooks are run concurrently and this method waits for 
         * them to finish.
         */
        static void runHooks() {
    	Collection<Thread> threads;
    	synchronized(ApplicationShutdownHooks.class) {
    	    threads = hooks.keySet();
    	    hooks = null;
    	}
    
    	for (Thread hook : threads) {
    	    hook.start();
    	}
    	for (Thread hook : threads) {
    	    try {
    		hook.join();
    	    } catch (InterruptedException x) { }
    	}
        }
    }
    

    当调用 Runtime.getRuntime().addShutdownHook(Thread hook)方法时,会间接调用 ApplicationShutdownHooks.add(Thread hook)将线程放到IdentityHashMap 中,Runtime.getRuntime().removeShutdownHook(Thread)用于删除一个钩子线程。 

    public void addShutdownHook(Thread hook) {
    	SecurityManager sm = System.getSecurityManager();
    	if (sm != null) {
    	    sm.checkPermission(new RuntimePermission("shutdownHooks"));
    	}
    	ApplicationShutdownHooks.add(hook);
        }
    public boolean removeShutdownHook(Thread hook) {
    	SecurityManager sm = System.getSecurityManager();
    	if (sm != null) {
    	    sm.checkPermission(new RuntimePermission("shutdownHooks"));
    	}
    	return ApplicationShutdownHooks.remove(hook);
        }

    当调用 System.exit(int status)方法时,会间接调用 Shutdown.exit(int status)方法,再调用sequence()-->runHooks() 方法。 

        /* Invoked by Runtime.exit, which does all the security checks.
         * Also invoked by handlers for system-provided termination events,
         * which should pass a nonzero status code.
         */
        static void exit(int status) {
    	boolean runMoreFinalizers = false;
    	synchronized (lock) {
    	    if (status != 0) runFinalizersOnExit = false;
    	    switch (state) {
    	    case RUNNING:	/* Initiate shutdown */
    		state = HOOKS;
    		break;
    	    case HOOKS:		/* Stall and halt */
    		break;
    	    case FINALIZERS:
    		if (status != 0) {
    		    /* Halt immediately on nonzero status */
    		    halt(status);
    		} else {
    		    /* Compatibility with old behavior:
    		     * Run more finalizers and then halt
    		     */
    		    runMoreFinalizers = runFinalizersOnExit;
    		}
    		break;
    	    }
    	}
    	if (runMoreFinalizers) {
    	    runAllFinalizers();
    	    halt(status);
    	}
    	synchronized (Shutdown.class) {
    	    /* Synchronize on the class object, causing any other thread
                 * that attempts to initiate shutdown to stall indefinitely
    	     */
    	    sequence();
    	    halt(status);
    	}
        }
        /* The actual shutdown sequence is defined here.
         *
         * If it weren't for runFinalizersOnExit, this would be simple -- we'd just
         * run the hooks and then halt.  Instead we need to keep track of whether
         * we're running hooks or finalizers.  In the latter case a finalizer could
         * invoke exit(1) to cause immediate termination, while in the former case
         * any further invocations of exit(n), for any n, simply stall.  Note that
         * if on-exit finalizers are enabled they're run iff the shutdown is
         * initiated by an exit(0); they're never run on exit(n) for n != 0 or in
         * response to SIGINT, SIGTERM, etc.
         */
        private static void sequence() {
    	synchronized (lock) {
    	    /* Guard against the possibility of a daemon thread invoking exit
    	     * after DestroyJavaVM initiates the shutdown sequence
    	     */
    	    if (state != HOOKS) return;
    	}
    	runHooks();
    	boolean rfoe;
    	synchronized (lock) {
    	    state = FINALIZERS;
    	    rfoe = runFinalizersOnExit;
    	}
    	if (rfoe) runAllFinalizers();
        }
        /* Run all registered shutdown hooks
         */
        private static void runHooks() {
    	/* We needn't bother acquiring the lock just to read the hooks field,
    	 * since the hooks can't be modified once shutdown is in progress
    	 */
    	for (Runnable hook : hooks) {
    	    try {
    		if (hook != null) hook.run();
    	    } catch(Throwable t) { 
    		if (t instanceof ThreadDeath) {
       		    ThreadDeath td = (ThreadDeath)t;
    		    throw td;
    		} 
    	    }
    	}
        }
    

    循环中的一个hook对象就是由 ApplicationShutdownHooks 的匿名块定义的,因此会调用 ApplicationShutdownHooks 类的 run() 方法,再调用它的runHooks()方法,这个 runHooks()方法内容如下。 

    /* Iterates over all application hooks creating a new thread for each
         * to run in. Hooks are run concurrently and this method waits for 
         * them to finish.
         */
        static void runHooks() {
    	Collection<Thread> threads;
    	synchronized(ApplicationShutdownHooks.class) {
    	    threads = hooks.keySet();
    	    hooks = null;
    	}
    
    	for (Thread hook : threads) {
    	    hook.start();
    	}
    	for (Thread hook : threads) {
    	    try {
    		hook.join();
    	    } catch (InterruptedException x) { }
    	}
        }

    从这个方法中取出所有的Thread ,然后将线程启动起来,最后通过 join() 方法等待各个线程结束的动作,换句话说,在进程关闭前,对多个回调任务的处理方式是每个任务单独有一个线程处理,而不是所有的任务在一个线程中串行处理。  

    ShutdownHook适用场景

    1. 程序正常退出
    2. 使用System.exit()
    3. 终端使用Ctrl+C触发的中断
    4. 系统关闭
    5. OutOfMemory宕机
    6. 使用Kill pid命令干掉进程(注:在使用kill -9 pid时,是不会被调用的)
    展开全文
  • 档案信息资源开发,就是档案部门根据社会需要采用专业方法和现代化技术,发掘、采集、加工、存储、传输所收藏档案中的有用信息,方便利用利用,以实现档案的价值和作用。


    1. 档案信息资源开发

      档案信息资源开发,就是档案部门根据社会需要采用专业方法和现代化技术,发掘、采集、加工、存储、传输所收藏档案中的有用信息,方便利用者利用,以实现档案的价值和作用。

    1.1 档案信息资源开发的意义

    1. 档案信息资源开发是实现档案自身价值的根本途径
    2. 档案信息资源开发是发展档案事业的需要
    3. 档案信息资源开发能使档案工作更好地为社会主义精神文明和物质文明服务

    1.2 档案信息资源开发的原则

    (1)资源为王(馆藏基础)原则
    (2)信息组织(有序化)原则
    (3)信息激活原则
    (4)有效利用原则
    (5)整体效益原则

    1.3 主要障碍和应对措施

    1.3.1 当前档案信息资源开发面临的主要障碍

    (一) 社会环境方面
     封闭落后的传统观念的束缚
     部分国民文化素质还不够高
     受经济发展水平的制约
    (二)档案部门自身方面
    1. 档案人员观念上的障碍
      一是受重藏轻用观念的制约、二是“保密保险,利用危险”的心态、三是有一部分人跟不上改革开放的新形势,自我封闭,孤芳自赏,因循守旧,限制了档案信息资源开发的积极性和主动性。

    2. 工作上的障碍
      1)没有建立起丰富的档案信息资源保障体系
      2)档案业务基础建设中还存在收集不齐全,归档率低,案卷质量不高,查找困难,保护不到位,标准化、规范化、现代化步伐不够快等因素,制约了档案信息资源开发。
      3)档案部门利用服务方式单一、范围狭窄。
      4)检索工具质量不够高和传输档案信息的手段落后。
      5)开发主体单一化

    (三)用户方面的障碍
      社会档案意识薄弱
      受利用者获取信息习惯的限制
      用户获取档案信息能力的制约

    1.3.2 档案信息资源开发应采取的措施

    (一)创新观念
    (二)做好宣传,改善环境
    (三)优化丰富馆(室)藏和健全档案信息的开发机构,确立资源与人员的保障关系
    (四)充分利用信息技术
    (五)以用户需求为导向,以创造名牌档案信息产品为目标
    (六)走特色开发之路

    展开全文
  • 摘要: 这是本系列的第2篇内容,将介绍在Docker和...第二篇:利用LXCFS提升容器资源可见性 第三篇:解决服务依赖 这是本系列的第2篇内容,将介绍在Docker和Kubernetes环境中解决遗留应用无法识别容器资源限制的问...

    摘要: 这是本系列的第2篇内容,将介绍在Docker和Kubernetes环境中解决遗留应用无法识别容器资源限制的问题。

    图片描述

    本系列文章记录了企业客户在应用Kubernetes时的一些常见问题

    第一篇:Java应用资源限制的迷思
    第二篇:利用LXCFS提升容器资源可见性
    第三篇:解决服务依赖
    这是本系列的第2篇内容,将介绍在Docker和Kubernetes环境中解决遗留应用无法识别容器资源限制的问题。

    Linuxs利用Cgroup实现了对容器的资源限制,但在容器内部依然缺省挂载了宿主机上的procfs的/proc目录,其包含如:meminfo, cpuinfo,stat, uptime等资源信息。一些监控工具如free/top或遗留应用还依赖上述文件内容获取资源配置和使用情况。当它们在容器中运行时,就会把宿主机的资源状态读取出来,引起错误和不便。

    LXCFS简介

    社区中常见的做法是利用 lxcfs来提供容器中的资源可见性。lxcfs 是一个开源的FUSE(用户态文件系统)实现来支持LXC容器,它也可以支持Docker容器。

    LXCFS通过用户态文件系统,在容器中提供下列 procfs 的文件。

    /proc/cpuinfo
    /proc/diskstats
    /proc/meminfo
    /proc/stat
    /proc/swaps
    /proc/uptime

    LXCFS的示意图如下

    图片描述

    比如,把宿主机的 /var/lib/lxcfs/proc/memoinfo 文件挂载到Docker容器的/proc/meminfo位置后。容器中进程读取相应文件内容时,LXCFS的FUSE实现会从容器对应的Cgroup中读取正确的内存限制。从而使得应用获得正确的资源约束设定。

    Docker环境下LXCFS使用

    注:

    • 本文采用CentOS 7.4作为测试环境,并已经开启FUSE模块支持。
    • Docker for Mac/Minikube等开发环境由于采用高度剪裁过的操作系统,无法支持FUSE,并运行LXCFS进行测试。
      安装 lxcfs 的RPM包
    wget https://copr-be.cloud.fedoraproject.org/results/ganto/lxd/epel-7-x86_64/00486278-lxcfs/lxcfs-2.0.5-3.el7.centos.x86_64.rpm
    yum install lxcfs-2.0.5-3.el7.centos.x86_64.rpm  

    启动 lxcfs

    lxcfs /var/lib/lxcfs &  

    测试

    $docker run -it -m 256m \
          -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw \
          -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw \
          -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw \
          -v /var/lib/lxcfs/proc/stat:/proc/stat:rw \
          -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw \
          -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw \
          ubuntu:16.04 /bin/bash
    
    root@f4a2a01e61cd:/# free
                  total        used        free      shared  buff/cache   available
    Mem:         262144         708      261436        2364           0      261436
    Swap:             0           0           0

    我们可以看到total的内存为256MB,配置已经生效。

    lxcfs 的 Kubernetes实践

    一些同学问过如何在Kubernetes集群环境中使用lxcfs,我们将给大家一个示例方法供参考。

    首先我们要在集群节点上安装并启动lxcfs,我们将用Kubernetes的方式,用利用容器和DaemonSet方式来运行 lxcfs FUSE文件系统。

    本文所有示例代码可以通过以下地址从Github上获得

    git clone https://github.com/denverdino/lxcfs-initializer
    cd lxcfs-initializer

    其manifest文件如下

    apiVersion: apps/v1beta2
    kind: DaemonSet
    metadata:
      name: lxcfs
      labels:
        app: lxcfs
    spec:
      selector:
        matchLabels:
          app: lxcfs
      template:
        metadata:
          labels:
            app: lxcfs
        spec:
          hostPID: true
          tolerations:
          - key: node-role.kubernetes.io/master
            effect: NoSchedule
          containers:
          - name: lxcfs
            image: registry.cn-hangzhou.aliyuncs.com/denverdino/lxcfs:2.0.8
            imagePullPolicy: Always
            securityContext:
              privileged: true
            volumeMounts:
            - name: rootfs
              mountPath: /host
          volumes:
          - name: rootfs
            hostPath:
              path: /

    注: 由于 lxcfs FUSE需要共享系统的PID名空间以及需要特权模式,所有我们配置了相应的容器启动参数。

    可以通过如下命令在所有集群节点上自动安装、部署完成 lxcfs,是不是很简单?:-)

    kubectl create -f lxcfs-daemonset.yaml

    那么如何在Kubernetes中使用 lxcfs 呢?和上文一样,我们可以在Pod的定义中添加对 /proc 下面文件的 volume(文件卷)和对 volumeMounts(文件卷挂载)定义。然而这就让K8S的应用部署文件变得比较复杂,有没有办法让系统自动完成相应文件的挂载呢?

    Kubernetes提供了 Initializer 扩展机制,可以用于对资源创建进行拦截和注入处理,我们可以借助它优雅地完成对lxcfs文件的自动化挂载。

    注: 阿里云Kubernetes集群,已经默认开启了对 Initializer 的支持,如果是在自建集群上进行测试请参见文档开启相应功能

    其 manifest 文件如下

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: lxcfs-initializer-default
      namespace: default
    rules:
    - apiGroups: ["*"]
      resources: ["deployments"]
      verbs: ["initialize", "patch", "watch", "list"]
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: lxcfs-initializer-service-account
      namespace: default
    ---
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: lxcfs-initializer-role-binding
    subjects:
    - kind: ServiceAccount
      name: lxcfs-initializer-service-account
      namespace: default
    roleRef:
      kind: ClusterRole
      name: lxcfs-initializer-default
      apiGroup: rbac.authorization.k8s.io
    ---
    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      initializers:
        pending: []
      labels:
        app: lxcfs-initializer
      name: lxcfs-initializer
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: lxcfs-initializer
          name: lxcfs-initializer
        spec:
          serviceAccountName: lxcfs-initializer-service-account
          containers:
            - name: lxcfs-initializer
              image: registry.cn-hangzhou.aliyuncs.com/denverdino/lxcfs-initializer:0.0.2
              imagePullPolicy: Always
              args:
                - "-annotation=initializer.kubernetes.io/lxcfs"
                - "-require-annotation=true"
    ---
    apiVersion: admissionregistration.k8s.io/v1alpha1
    kind: InitializerConfiguration
    metadata:
      name: lxcfs.initializer
    initializers:
      - name: lxcfs.initializer.kubernetes.io
        rules:
          - apiGroups:
              - "*"
            apiVersions:
              - "*"
            resources:
              - deployments

    注: 这是一个典型的 Initializer 部署描述,首先我们创建了service account lxcfs-initializer-service-account,并对其授权了 “deployments” 资源的查找、更改等权限。然后我们部署了一个名为 “lxcfs-initializer” 的Initializer,利用上述SA启动一个容器来处理对 “deployments” 资源的创建,如果deployment中包含 initializer.kubernetes.io/lxcfs为true的注释,就会对该应用中容器进行文件挂载

    我们可以执行如下命令,部署完成之后就可以愉快地玩耍了

    kubectl apply -f lxcfs-initializer.yaml

    下面我们部署一个简单的Apache应用,为其分配256MB内存,并且声明了如下注释 “initializer.kubernetes.io/lxcfs”: “true”

    其manifest文件如下

    apiVersion: apps/v1beta1
    kind: Deployment
    metadata:
      annotations:
        "initializer.kubernetes.io/lxcfs": "true"
      labels:
        app: web
      name: web
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: web
          name: web
        spec:
          containers:
            - name: web
              image: httpd:2
              imagePullPolicy: Always
              resources:
                requests:
                  memory: "256Mi"
                  cpu: "500m"
                limits:
                  memory: "256Mi"
                  cpu: "500m"

    我们可以用如下方式进行部署和测试

    $ kubectl create -f web.yaml 
    deployment "web" created
    
    $ kubectl get pod
    NAME                                 READY     STATUS    RESTARTS   AGE
    web-7f6bc6797c-rb9sk                 1/1       Running   0          32s
    $ kubectl exec web-7f6bc6797c-rb9sk free
                 total       used       free     shared    buffers     cached
    Mem:        262144       2876     259268       2292          0        304
    -/+ buffers/cache:       2572     259572
    Swap:            0          0          0

    我们可以看到 free 命令返回的 total memory 就是我们设置的容器资源容量。

    我们可以检查上述Pod的配置,果然相关的 procfs 文件都已经挂载正确

    $ kubectl describe pod web-7f6bc6797c-rb9sk
    ...
        Mounts:
          /proc/cpuinfo from lxcfs-proc-cpuinfo (rw)
          /proc/diskstats from lxcfs-proc-diskstats (rw)
          /proc/meminfo from lxcfs-proc-meminfo (rw)
          /proc/stat from lxcfs-proc-stat (rw)
    ...

    在Kubernetes中,还可以通过 Preset 实现类似的功能,篇幅有限。本文不再赘述了。

    总结

    本文介绍了通过 lxcfs 提供容器资源可见性的方法,可以帮助一些遗留系统更好的识别容器运行时的资源限制。

    同时,在本文中我们介绍了利用容器和DaemonSet的方式部署lxcfs FUSE,这不但极大简化了部署。也可以方便地利用Kubernetes自身的容器管理能力,支持lxcfs进程失效时自动恢复,在集群伸缩时也可以保证节点部署的一致性。这个技巧对于其他类似的监控或者系统扩展都是适用的。

    另外我们介绍了利用Kubernetes的扩展机制 Initializer,实现对 lxcfs 文件的自动化挂载。整个过程对于应用部署人员是透明的,可以极大简化运维复杂度。同时利用类似的方法,我们可以灵活地定制应用部署的行为,满足业务的特殊要求。

    阿里云Kubernetes服务 全球首批通过Kubernetes一致性认证,简化了Kubernetes集群生命周期管理,内置了与阿里云产品集成,也将进一步简化Kubernetes的开发者体验,帮助用户关注云端应用价值创新。

    原文链接

    阅读更多干货好文,请关注扫描以下二维码:
    图片描述

    展开全文
  • 利用yarn多队列实现hadoop资源隔离

    万次阅读 2016-12-11 18:13:18
    大数据处理离不开hadoop集群的部署和管理,对于本来硬件资源就不多的创业团队来说,做好资源的共享和隔离是很有必要的,毕竟不像BAT那么豪,那么怎么样能把有限的节点同时分享给多组用户使用而且互不影响呢,我们来...

    大数据处理离不开hadoop集群的部署和管理,对于本来硬件资源就不多的创业团队来说,做好资源的共享和隔离是很有必要的,毕竟不像BAT那么豪,那么怎么样能把有限的节点同时分享给多组用户使用而且互不影响呢,我们来研究一下yarn多队列做资源隔离

    请尊重原创,转载请注明来源网站www.shareditor.com以及原始链接地址

    CapacityScheduler

    使用过第一代hadoop的同学应该比较熟悉mapred.job.map.capacity/mapred.job.reduce.capacity这个参数,无论是map还是reduce都可以配置capacity(也就是并发数),表示同时可以有多少个map(或reduce)运行,通过这个参数可以限制一个任务同时占用的资源(节点)数,这样不至于影响其他任务的执行。

    在这里有人会问:我把任务的priority设置成VERY LOW不就行了吗?其实这样在某些场景下不能解决全部问题,因为假如你一个VERY LOW的任务刚启动时没有其他人的任务,那么会先占用所有节点,如果你的每一个task运行时间都是1天,那么其他任务就算优先级再高也只能傻等一天,所以才有必要做资源隔离

    第二代hadoop因为使用yarn做资源管理,没有了槽位的概念,所以就没有了capacity。但是在yarn中专门有了CapacityScheduler这个组件。这是一个可插装的调度器,它的用途就是对多用户实现共享大集群并对每个用户资源占用做控制

    对于很豪的公司来说,每个用户(团队)自己有一个hadoop集群,这样可以提高自身的稳定性和资源供应,但是确降低了资源利用率,因为很多集群大多数时间都是空闲的。CapacityScheduler能实现这样的功能:每个组固定享有集群里的一部分资源,保证低保,同时如果这个固定的资源空闲,那么可以提供给其他组来抢占,但是一旦这些资源的固定使用者要用,那么立即释放给它使用。这种机制在实现上是通过queue(队列)来实现的。当然CapacityScheduler还支持子队列(sub-queue),

    hadoop资源分配的默认配置

    我在博客中已经描述了整体一套hadoop搭建的方法。那么在搭建完成后我们发现对于资源分配方面,yarn的默认配置是这样的

    也就是有一个默认的队列

    事实上,是否使用CapacityScheduler组件是可以配置的,但是默认配置就是这个CapacityScheduler,如果想显式配置需要修改 conf/yarn-site.xml 内容如下:

    <property>
    <name>yarn.resourcemanager.scheduler.class</name>
    <value>
    org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler
    </value>
    </property>

    上面图中标明了默认队列是default,是使用了CapacityScheduler的默认配置

    我们看一下有关这里的default是怎么配置的,见capacity-scheduler.xml配置:

    <property>
        <name>yarn.scheduler.capacity.root.queues</name>
        <value>default</value>
        <description>
          The queues at the this level (root is the root queue).
        </description>
      </property>

    这里的配置项格式应该是yarn.scheduler.capacity.<queue-path>.queues,也就是这里的root是一个queue-path,因为这里配置了value是default,所以root这个queue-path只有一个队列叫做default,那么有关default的具体配置都是形如下的配置项:

    yarn.scheduler.capacity.root.default.capacity:一个百分比的值,表示占用整个集群的百分之多少比例的资源,这个queue-path下所有的capacity之和是100

    yarn.scheduler.capacity.root.default.user-limit-factor:每个用户的低保百分比,比如设置为1,则表示无论有多少用户在跑任务,每个用户占用资源最低不会少于1%的资源

    yarn.scheduler.capacity.root.default.maximum-capacity:弹性设置,最大时占用多少比例资源

    yarn.scheduler.capacity.root.default.state:队列状态,可以是RUNNING或STOPPED

    yarn.scheduler.capacity.root.default.acl_submit_applications:哪些用户或用户组可以提交人物

    yarn.scheduler.capacity.root.default.acl_administer_queue:哪些用户或用户组可以管理队列

    当然我们可以继续以root.default为queue-path创建他的子队列,比如:

    <property>
        <name>yarn.scheduler.capacity.root.default.queues</name>
        <value>a,b,c</value>
        <description>
          The queues at the this level (root is the root queue).
        </description>
      </property>

    这是一个树结构,一般和公司的组织架构有关

    配置好上述配置后执行

    yarn rmadmin -refreshQueues

    生效后发现yarn队列情况类似下面的样子(配置了两个队列:research和default):

    如果希望自己的任务调度到research队列,只需在启动任务时指定:mapreduce.job.queuename参数为research即可

    展开全文
  • 大数据处理离不开hadoop集群的部署和管理,对于本来硬件资源就不多的创业团队来说,做好资源的共享和隔离是很有必要的,毕竟不像BAT那么豪,那么怎么样能把有限的节点同时分享给多组用户使用而且互不影响呢,我们来...
  • 如果某个功能需要实现无限循环,肯定是不能在UI线程中执行的,想到的第一种办法肯定是放在新建的线程里。 ...但是开辟新线程是需要消耗系统资源的,因为在...这样以后利用自身调用,run里面的代码每1s执行一次。
  • 但是整个CORS体系不限于此,在它们背后隐藏着一系列的类型,我们将会利用本章余下的内容对此作全面讲述,今天我们就来讨论一下用于定义CORS授权策略的EnableCorsAttribute特性背后的故事。目录 一
  • 5.这样我们的多语言其实就差不多实现了,还差的就是利用资源文件开始大量的翻译! 我们随意选择一个页面,转到他的设计页面,然后工具/生成本地资源 这样就会多出一个文件夹App_LocalResources,里面还会多出一个和选择...
  • Github Awesome项目又增新成员——Awesome Indie(Github)可以帮助开发者创建可盈利副业的资源收集项目。一般来说开发者自己尝试从代码中赚钱,这其实比较困难。该项目将尝试策划一系列的资源,以帮助对此有兴趣...
  • 资源编目与规范

    千次阅读 2010-11-10 08:52:00
    <br /> 浅析利用MARC格式进行网络资源编目 <br />[摘要]探析了网络环境下MARC格式的结构、特点和编目的优势及实际应用。 [关键词]MARC格式元数据网络资源编目 [分类号]G254.36 随着...
  • C#中创建资源和使用资源

    千次阅读 2010-08-25 22:21:00
    资源文件在程序设计中有着自身独特的优势,他独立于源程序,这样资源文件就可以被多个程序使用。同时在程序设计的时候,有时出于安全或者其他方面因素的考虑,把重要东西存放在资源文件中,也可以达到保密、安全的...
  • 在大数据时代,为了合理分配大规模集群的资源,满足日益增多的服务和任务的资源需求,出现了诸如Borg,...虽然架构不同,但是它们的设计目标(简单合理的利用集群资源)和主要职责(为任务分配主机资源)都是一样的。
  • 资源分配与调度

    千次阅读 2019-12-31 19:07:29
    1、保证资源的高利用率; 2、在“合理”时间内使所有顾客有获得所需资源的机会; 3、对不可共享的资源实施互斥使用; 4、防止由资源分配不当而引起的死锁。 对资源的管理应包括以下几个方面: 1、资源管理的描述--...
  • JavaScript第二十二章 跨域资源共享

    万次阅读 2019-11-13 20:34:59
    跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。 广义的跨域: 资源跳转: A链接、重定向、表单提交 资源嵌入: 、什么是同源策略? 同源策略/SOP(Same origin policy)是一种约定,...
  • PMP-34项目资源管理

    千次阅读 2019-06-15 14:47:52
    资源管理的过程3. 规划资源管理4. 估算活动资源5. 获取资源6. 建设团队6.1 团队建设的五个阶段6.2 工具和技术6.3 激励理论7. 管理团队7.1 冲突管理7.1 冲突解决方法8. 控制资源 1. 概念 项目资源管理包括 实物...
  • 如何在网上下载自己需要的资源

    千次阅读 2018-02-12 00:00:00
    本文来自作者 曹某某 在 GitChat 上分享 「如何在网上下载自己需要的资源」,「阅读原文」查看交流实录。「文末高能」编辑 | 哈比通过网络获取需要的软件、文档等资源是每个人必须掌握的技能。这篇文...
  • Yarn资源调度工作原理

    万次阅读 2018-07-01 19:13:00
    由于Yarn良好的兼容性和扩展性,目前可以支持大部分数据引擎,所以了解Yarn的资源调度原理很有必要,Yarn主要由四个重要角色组成:ResourceManager:顾名思义资源管理器,主要负责资源管理和调度,ResourceManager...
  • 云计算设计模式(五)——计算资源整合模式 合并多个任务或操作成一个单一的计算单元。这种模式可以提高计算资源利用率,并降低与云托管的应用程序进行计算处理相关的成本和管理开销。
  • CSDN资源共享规范

    万次阅读 多人点赞 2019-12-11 09:49:29
    CSDN资源共享规范 上传及下载规则 1、CSDN(包括CSDN网站与相应客户端、自媒体平台、主运营网站等)是为广大用户提供资源(包括但不限于文章、文档、音频、视频、图片、课程、软件、源代码等相关资源)共享的网络...
  • 集群资源管理与调度

    千次阅读 2016-08-27 21:59:08
    缺点:资源整体利用率不高,经常会出现集群中有些计算系统资源不足,但是有些计算系统存在大量闲置资源的情形。 独立资源管理:在集群硬件层上抽象出一个功能独立的集群资源管理系统,将所有可用资源当成一个整体来...
  • 创业服务资源获取的途径有哪些?

    万次阅读 2018-10-12 02:48:23
    创业者关注的更多是自身资源从哪里积累,怎么样积累,需要哪些方法和技能等等,因为资源对初创企业来说是很重要的一部分,创成汇作为专业的创业者服务平台,以创新创业成果转化为服务方向的平台,有效的整合创业...
  • 需求:小程序因为自身上传包大小的限制(每个包2M,使用分包总共可以上传8M),所以小程序的静态资源主要是放在服务器端(主要是图片资源)。但是从服务器获取图片时有可能出现下面一种情况: 返回的是图片的url...
  • 制造资源计划 制造资源计划(MRPII,Manufacturing Resources Planning),是指企业对其生产系统和经营活动建立一种计划模型,并通过利用该模型把企业的制造资源和经营任务的需求进行平衡,从而保证企业目标的实现...
  • 1.1.2 页面资源加载缓慢 H5 页面从服务器获得,并存储在 Android手机内存里: H5页面一般会比较多 每加载一个 H5页面,都会产生较多网络请求: HTML 主 URL 自身的请求; HTML外部引用的JS、CSS、字体文件,图片也...
  • Unity资源打包之Assetbundle

    万次阅读 2014-04-22 09:31:53
    在手游的运营过程中,更新资源是比不可少的。资源管理第一步是资源打包。...利用AssetBundle,可以将几乎所有的资源都打包封装,便于客户端更新下载新的资源。 (转载请注明原文出处http://blog.csdn.net/janeky/artic
  • 最近研究了一下如何从外部动态调用图片的问题,从而研究了图片资源的使用方法。网上最常见的帖子是这个,感觉总结的还不错。 http://www.cnblogs.com/lzjsky/archive/2012/08/20/2647471.html  总的来说,就...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 252,576
精华内容 101,030
关键字:

如何利用自身资源