估计大家也可能听过Docker这项技术(在论坛上、招聘技能上、交流群上等等),要是不了解Docker,都不好意思在网上冲浪的时候吹牛逼了。
  
  所以这几天学了一下Docker,总结了Docker入门的相关知识,分享给大家(好让我们一起吹牛逼)。
  
  Docker LoGo
  
  I need a doctor,call me a doctor. I need a doctor, doctor, to bring me back to life .
  
  一、为什么需要Docker
  
  Docker 是世界领先的软件容器平台。
  
  开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。
  
  运维人员利用 Docker 可以在隔离容器中并行运行和管理应用,获得更好的计算密度。
  
  企业利用 Docker 可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为 Linux 和 Windows Server 应用发布新功能。
  
  1.1环境(切换/配置)麻烦
  
  一般我们写程序的,能接触到好几个环境:
  
  自己写代码的环境叫做开发环境。
  
  给测试去跑的环境叫做测试环境。
  
  测试完可以对外使用的叫做生产环境。
  
  其实我们在学习编程中,很多时间都浪费在“环境”上:
  
  如果我现在重装了系统,我想要跑我的war/jar包,我得去安装一下JDK、Tomcat、MySQL等配置各种的环境变量才能跑起来。
  
  开开心心地跟着博主给出的步骤去写Demo,但总是有Bug。(这里我将版本/依赖也归纳在环境的范畴里边)。
  
  好不容易在测试环境下跑起来了,在生产环境就各种出错!
  
  跟着教学视频做分布式/集群的项目,跑一堆的虚拟机,每个虚拟机都要安装对应的环境。
  
  所以就有个笑话《千万不要跟程序员说,你的代码有bug》:
  
  他的第一反应是你的环境有问题,第二就是你是傻逼不会用吧。
  
  你要跟他这么说:“这个程序运行的怎么运行的跟预期不一样,是我操作有问题吗?”。
  
  这货就会第一反应“我擦,这是不是出bug了?”
  
  1.2应用之间需要隔离
  
  比如我写了两个应用(网站),这两个应用部署在同一台服务器上,那可能会出现什么问题?
  
  如果一个应用出现了问题,导致CPU占100%。那另一个应用也会受到关联,跟着一起凉凉了。
  
  这两个应用是完全不同技术栈的应用,比如一个PHP,一个.NET。这两个应用各种的依赖软件都安装在同一个服务器上,可能就会造成各种冲突/无法兼容,这可能调试就非常麻烦了。
  
  二、Docker是如何解决上述的问题的
  
  2.1解决环境(切换/配置)
  
  不知道大家有没有装过系统,比如说装Linux虚拟机,重装Windows系统,都是需要镜像的。
  
  镜像
  
  有了这个镜像,我们就可以运行这个镜像,来进行安装系统的操作(此处省略N个下一步),于是我们的系统就装好了。一般来说,我们去官方渠道下载的镜像,都是纯净的。比如去官方下载Windows镜像,装完后之后桌面只有一个回收站。
  
  但有过了解装系统的同学可能就会知道,有的镜像装完可能还有360这些软件,但系统的的确确是变了。简单来说,就是这些镜像添加了其他的东西(比如360软件、腾讯、千千静听等等软件)。
  
  Docker也是这种思路,可以将我们的想要的环境构建(打包)成一个镜像,然后我们可以推送(发布)到网上去。想要用这个环
  
  境的时候,在网上拉取一份就好了。
  
  有了Docker,我们在搭环境的时候,跟以前的方式就不一样了。
  
  之前:在开发环境构建出了一个war包,想跑到Linux下运行。我们得先在Linux下载好Java、Tomcat、MySQL,配置好对应的环境变量,将war包丢到Tomcat的webapps文件夹下,才能跑起来。
  
  现在:在Linux下直接拉取一份镜像(各种环境都配好了),将镜像运行起来,把war包丢进去就好了。
  
  DockerHub提供了很多镜像
  
  将Docker的镜像运行起来就是一两秒的事情而已,十分方便的。
  
  2.2解决应用之间隔离
  
  说到这里,就得提出一个大家可能不认识的概念:LXC(Linux Containers)--->Linux容器。
  
  2.2.1Linux容器
  
  在Linux内核中,提供了cgroups功能,来达成资源的区隔化。它同时也提供了名称空间(namespace)区隔化的功能,使应用程序看到的操作系统环境被区隔成独立区间,包括进程树,网络,用户id,以及挂载的文件系统。
  
  简单来说就是:LXC是一个为Linux内核包含特征的用户接口。通过强大的API和简单的工具,它可以让Linux用户轻松的创建和托管系统或者应用程序容器。
  
  2.2.2回到Docker
  
  我们在翻看Docker的官方文档的时候,也很容易看见cgroup和namespace这两个名词:
  
  官方文档截图
  
  来源维基百科:
  
  Early versions of Docker used LXC as the container execution driver, though LXC was made optional in v0.9 and support was dropped in Docker v1.10.
  
  lxc是早期版本docker的一个基础组件,docker 主要用到了它对 Cgroup 和 Namespace 两个内核特性的控制。新的Docker版本已经移除了对LXC的support。
  
  2.2.3Docker在Windows和Mac
  
  上面说了,Docker底层用的Linux的cgroup和namespace这两项技术来实现应用隔离,那Windows和Mac用户能用Docker吗?
  
  之前,Windows和Mac使用Docker实际上就是跑了一层Linux虚拟机。
  
  比如在Windows下安装的是Docker Toolbox,它需要Oracle Virtual Box来跑Docker
  
  现在,Windows和Mac都已经原生支持Docker了。但需要一些安装的条件,详情可以查看官网
  
  比如Windows:Docker for Windows requires 64bit Windows 10 Pro and Microsoft Hyper-V
  
  参考资料:
  
  Windows 原生 Docker 正式商用
  
  http://blog.daocloud.io/windows-docker/
  
  三、虚拟机和Docker
  
  说到应用隔离和镜像,我就想起了虚拟机。今年下半年(此处省略.....),文体两开花(此处省略.....),要是我写文章写得不好,我是需要向XX谢罪的。
  
  估计大家都用过虚拟机,虚拟机也能实现对应用的隔离,安装特定的镜像也能跑出我们想要的环境。虚拟机已经发展了很久了,为什么我们还需要Docker呢?
  
  这部分内容在官网也有相关的介绍:
  
  http://www.docker-cn.com/what-container#/virtual_machines
  
  容器和Docker的区别
  
  一句话总结:Docker容器比虚拟机轻量多了!
  
  最后
  
  Docker可以干嘛?
  
  将一整套环境打包封装成镜像,无需重复配置环境,解决环境带来的种种问题。
  
  Docker容器间是进程隔离的,谁也不会影响谁。
  
  其实这篇文章主要是讲为什么我们需要Docker(在学习一项技术之前,必须要知道这项技术是用来干嘛的),Docker的一些概念和命令我还没介绍(留到下一篇啦)。如果还没看过【生活现场】从搬家到容器技术docker应用场景解析,可以先去看看~
  
  1.      Bagging
  
  Bagging即套袋法,其算法过程如下:
  
  从原始样本集中抽取训练集。每轮从原始样本集中使用Bootstraping的方法抽取n个训练样本(在训练集中,有些样本可能被多次抽取到,而有些样本可能一次都没有被抽中)。共进行k轮抽取,得到k个训练集。(k个训练集之间是相互独立的)
  
  每次使用一个训练集得到一个模型,k个训练集共得到k个模型。(注:这里并没有具体的分类算法或回归方法,我们可以根据具体问题采用不同的分类或回归方法,如决策树、感知器等)
  
  对分类问题:将上步得到的k个模型采用投票的方式得到分类结果;对回归问题,计算上述模型的均值作为最后的结果。(所有模型的重要性相同)
  
  2.      算法设计过程
  
  2.1.    随机采样方法
  
  样本总数150条(Iris数据集)
  
  抽样方法是有放回随机抽样。对150个样本的数据集,进行150次又放回随机采样,这样得到具有和原样本空间同等大小的样本集。
  
  这样操作clip_image002次,得到训练样本。33个用决策树C50,34个朴素贝叶斯,33个用KNN。
  
  2.2.    模型评价方法
  
  2.2.1.  包外错误率
  
  由抽样方法可知,每次抽样大约有36.8%的数据未被抽到,这36.8%将作为包外数据clip_image004,包外错误率:
  
  clip_image006
  
  clip_image008
  
  图 1 包外错误率
  
  2.2.2.  成对多样性度量
  
  a->两个个体学习器对同一条数据(h1=h2=Class),分类都与原数据集分类相同的总和
  
  b->两个个体学习器对同一条数据(h1=class,h2!=Class)
  
  c->两个个体学习器对同一条数据(h1!=class,h2=Class)
  
  d->两个个体学习器对同一条数据(h1!=class,h2!=Class),分类都与原数据集分类都不相同的总和
  
  K统计量
  
  clip_image010
  
  Q统计量
  
  clip_image012
  
  相关系数
  
  clip_image014
  
  不一致度量
  
  clip_image016
  
  表1两个分类器的分类结果组合情况
  
  clip_image018
  
  clip_image020
  
  clip_image022
  
  clip_image024
  
  clip_image026
  
  clip_image028
  
  clip_image030
  
  clip_image032
  
  图2 多样性度量矩阵
  
  clip_image034
  
  2.3.    伪代码
  
  输入:clip_image036,弱分类器迭代次数T=100,弱分类器B
  
  输出:clip_image038  %集成学习器
  
  过程:
  
  for i to T
  
  clip_image040           %Bagging采样,总共T次
  
  clip_image042     %获得包外测试集
  
  clip_image044        %学习器训练得到个体学习器
  
  clip_image046  %包外错误率
  
  end
  
  for i to T
  
  for j=i+1 to T
  
  统计a,b,c,d
  
  计算clip_image048
  
  clip_image050  %多样性测度矩阵
  
  end
  
  end
  
  3.      附录
  
  数据集简介:
  
  表2 iris
  
  sepal length
  
  萼片长度
  
  sepal width
  
  萼片宽度
  
  petal length
  
  花瓣长度
  
  petal width
  
  花瓣宽度
  
  Class
  
  Iris-setosa -> 1
  
  Iris-versicolor -> 2
  
  Iris-virginica-> 3
  
  R语言中的坑
  
  第一次用R语言
  
  例如
  
  public class ExecutionOrder
  
  {
  
  static Thread t1;
  
  static Thread t2;
  
  public static void WriteFinished(string threadName)
  
  {
  
  switch (threadName)
  
  {
  
  case "T1":
  
  Console.WriteLine(www.tkcyl1.com/);
  
  Console.WriteLine(www.078881.cn"T1 Finished");
  
  break;
  
  case "T2":
  
  Console.WriteLine();
  
  Console.WriteLine("T2 Finished");
  
  break;
  
  }
  
  }
  
  public static void MainGo(www.feifanyule.cn)
  
  {
  
  t1 = new Thread(new ThreadStart(Increment));
  
  t2 = new Thread(new ThreadStart(Increment));
  
  t1.Name =www.michenggw.com "T1";
  
  t2.Name = "T2";
  
  t1.Start(www.dasheng178.com);
  
  t2.Start();
  
  Console.ReadLine();
  
  }
  
  public static void Increment(yongshiyule178.com)
  
  {
  
  for (long i=1;i<=1000000;i++)
  
  {
  
  if (i%10000==0)
  
  {
  
  Console.WriteLine("{"+Thread.CurrentThread.Name+"}");
  
  }
  
  }
  
  WriteFinished(Thread.CurrentThread.Name);
  
  testData<-read.csv("G:\\testData.csv"www.xiaomiyulezc.com , header = FALSE)
  
  将数据集导入之后 调用相关KNN NavieBayes等函数无法成功 原因是在导入的时候 数据集的class列 被自动转换成了整型(int)
  
  tempTrain[,nc]<-as.factor(tempTrain[,nc])
  
  调用as.factor()将class转换为因子 就可解决
  
  还有 代码重复利用率低的问题 在下一次更新代码之中 可以解决

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐