[OpenStack] Nova中的线程模型,openstacknova


1) greenlet - python中的协程库

1.1) 什么是协程 (Coroutine)


Coroutine Wiki

http://en.wikipedia.org/wiki/Coroutine

  • CoRoutine是在Thread基础上的再次切分. 每一个Process可以包含多个Thread, 每个线程包含多个CoRoutine
  • 在任何时刻, 同一个Thread内只能有一个CoRoutine在运行.
  • 协程并不是真正的并发, 协程只是同一线程内不同代码的切换. 因此同一Thread内的CoRoutine之间如果访问共享数据, 不需要资源保护.

1.2) python中的 Coroutine 实现 - greenlet

greentlet 是python的Coroutine实现包. 用法可以参考官方的例子
from greenlet import greenlet

def test1():
    print 12
    gr2.switch()
    print 34

def test2():
    print 56
    gr1.switch()
    print 78

gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch()

greenlet.greenlet 类 就是 Coroutine 的python 实现, 不同的 greenlet协程之间, 可以调用switch 函数来做切换.
从这段代码也可以看出来, greenlet只实现了基础的Coroutine协程功能. 如果想在项目中直接使用, 我们还要
  • 和epoll集成, 通过对IO的select, 来选择要切换的时机
  • 一个通用的自动切换/调度程序
  • 更多的线程高级概念: Event, Semaphore, ThreadPool等等
所以我们就需要使用eventlet库

2) eventlet - 基于协程的绿色线程

eventlet 库是python下面的一个多线程 IO框架, eventlet通过对epoll 和 greenlet的封装, 实现了 IO复用, 线程池等等高级概念 通过eventlet, 我们就不用直接和greenlet库打交道了.
eventlet中经常使用的几个类
GreenThread: 绿色线程. GreenThread 是 eventlet 类的子类, 所以 GreenThread 就是一个协程 Coroutine
  • sleep(): 向调度器发出信号, 从当前的GreenThread 切换到别的GreenThread
  • spawn(): 启动一个新的GreenThread 

greenpool: 绿色线程池. 包含了1到n个greenthread. 
  • spawn(): 让greenpool 使用pool中的greenthread来运行客户端提交的任务. 如果pool中没有可用的greenthread, spawn()会一直阻塞等待到有可用的greenthread为止

event: 事件类
  •  wait(): 让调用event.wait()的greenthread处于阻塞等待状态, 直到别的greenthread调用了event.send()为止
  • send(): 发送信号, 让所有在event上阻塞的greenthread 结束等待状态, 继续运行.

semaphore: 信号量
  • acquire: 获取semaphore. 同一时刻, 只能有一个greenthread获得semaphore, 在无法获得semaphore时, greenthread会处于阻塞等待状态
  • release: 释放已经获得的semaphre

3) Nova Service - 基于GreenThread的业务封装

nova service则是对eventlet包的进一步封装
  • 每一个service都包含了一个greenthread pool, 把业务代码跑在greenthread上.
  • 每一个service 包含了event变量, 来等待所有greenthread全部结束







openstack组件问题

OpenStack其实有三个与存储相关的组件,这三个组件被人熟知的程度和组件本身出现时间的早晚是相符的,按熟悉程度排列如下:
Swift——提供对象存储 (Object Storage),在概念上类似于Amazon S3服务,不过swift具有很强的扩展性、冗余和持久性,也兼容S3 API
Glance——提供虚机镜像(Image)存储和管理,包括了很多与Amazon AMI catalog相似的功能。(Glance的后台数据从最初的实践来看是存放在Swift的)。
Cinder——提供块存储(Block Storage),类似于Amazon的EBS块存储服务,目前仅给虚机挂载使用。
(Amazon一直是OpenStack设计之初的假象对手和挑战对象,所以基本上关键的功能模块都有对应项目。除了上面提到的三个组件,对于AWS中的重要的EC2服务,OpenStack中是Nova来对应,并且保持和EC2 API的兼容性,有不同的方法可以实现)
三个组件中,Glance主要是虚机镜像的管理,所以相对简单;Swift作为对象存储已经很成熟,连CloudStack也支持它。Cinder是比较新出现的块存储,设计理念不错,并且和商业存储有结合的机会,所以厂商比较积极。
Swift
关于Swift的架构和部署讨论,除了官方网站,网上也有很多文章,这里就不重复.(也可以参考我之前在OpenStack中国行活动中上海站演讲的PPT)。从开发上看,最近也没有太大的结构性调整,所以我想主要说说比较适用的应用领域好了。
从我所了解的实际案例来看,Swift出现的领域有4个,(应该还有更多,希望大家看到实际用例能够指教)
1.网盘。
Swift的对称分布式架构和多proxy多节点的设计导致它从基因里就适合于多用户大并发的应用模式,最典型的应用莫过于类似Dropbox的网盘应用,Dropbox去年底已经突破一亿用户数,对于这种规模的访问,良好的架构设计是能够支撑的根本原因。
Swift的对称架构使得数据节点从逻辑上看处于同级别,每台节点上同时都具有数据和相关的元数据。并且元数据的核心数据结构使用的是哈希环,一致性哈希算法对于节点的增减都只需重定位环空间中的一小部分数据,具有较好的容错性和可扩展性。另外数据是无状态的,每个数据在磁盘上都是完整的存储。这几点综合起来保证了存储的本身的良好的扩展性。
另外和应用的结合上,Swift是说HTTP协议这种语言的,这使得应用和存储的交互变得简单,不需要考虑底层基础构架的细节,应用软件不需要进行任何的修改就可以让系统整体扩展到非常大的程度。
2.IaaS公有云
Swift在设计中的线性扩展,高并发和多租户支持等特性,使得它也非常适合做为IaaS的选择,公有云规模较大,更多的遇到大量虚机并发启动这种情况,所以对于虚机镜像的后台存储具体来说,实际上的挑战在于大数据(超过G)的并发读性能,Swift在OpenStack中一开始就是作为镜像库的后台存储,经过RACKSpace上千台机器的部署规模下的数年实践,Swift已经被证明是一个成熟的选择。
另外如果基于IaaS要提供上层的SaaS 服务,多租户是一个不可避免的问题,Swift的架构设计本身就是支持多租户的,这样对接起来更方便。
3.备份归档
RackSpace的主营业务就是数据的备份归档,所以Swift在这个领域也是久经考验,同时他们还延展出一种新业务--“热归档”。由于长尾效应,数据可能被调用的时间窗越来越长,热归档能够保证应用归档数据能够在分钟级别重新获取,和传统磁带机归档方案中的数小时......余下全文>>
 

OpenStack怎读

分开读就可以啊 Open 开放的 Stack堆叠,直译 一大堆开源软件的堆叠
 

相关内容