月度归档:2017年03月

儿童编程语言

一、Scratch

Scratch 是由麻省理工学院媒体实验室 Lifelong Kindergarten 小组开发的一种编程语言和在线社区。Scratch 的服务是免费的,它允许你的孩子创建自己的动画,游戏和故事。你的孩子可以通过 Scratch 的在线社区与世界各地的其他人一同分享创造的成果。

这个也是王颢老师经常在公众号《科学小实验》提到的,由于使用的人很多,有很多参考的作品,对于缺乏想象力的王颢老师来说是一大福音。

而且这种语言还有机器人版,所以和开源硬件结合起来真是绝代双骄,绝对比乐高的Mindstorms火爆。对了忘记告诉大家,Mindstorms是乐高和MIT合作产生的,跟Scratch是一个爸爸的。只是呢,Mindstorms被乐高抱养走了,Scratch还留在家里,哈哈!

以后王颢老师充分发挥自己硬件特长,将这个语言扩展到4岁以上的孩子,要是爸爸们对机器人感兴趣,也可以和孩子一块玩哦!

 

http://www.scratchchina.com/bbs/forum.php

http://www.scratchplus.cn/

 

二、Etoys

Etoys 是一个易于使用的编程工具,孩子们可以用它来创建他们自己的游戏,模型和故事。Etoys 的开发项目包含了图形、动画对象、音乐、声音、扫描图片和文本。Etoys 是免费的,可以自由使用。

这个也蛮简单的,可以学学,当然大家先了解了解。另外 王颢老师精力有限,只教大家其中一种就行,感兴趣的可以自学。

http://www.squeakland.org/download/

 

三、Alice

Alice 一个可免费使用的 3d 编程工具,它支持创建一个讲述故事的动画,并在网络上将交互行为和视频进行分享。Alice 的主要目的是给你的孩子接触基本的面向对象编程。通过使用 Alice,学生可以学习如何创建动画电影(包含人、动物和车辆)和简单的视频游戏。

王颢老师看评论,感觉偏向女孩子,但是用起来也比较简单。

四、Hopscotch

Hopscotch 的宣言是为每个人设计编程。通过使用 Hopscotch,你可以很轻松的教授给你的孩子基本的编程知识。目前 Hopscotch 应用只针对 iPad 用户提供免费下载。Hopscotch 可以让你的孩子在通过拖拽代码块来完成对游戏、故事、动画和其它交互式程序的开发。总之,这是一款只需要在 iPad 上通过摇晃、倾斜甚至呼喊就能完成程序字符控制的工具。

要是有ipad的,可以下载试试,可能是英文的,但是王颢老师觉得对于不识字的孩子来说,英文更好入手。

五、Kodable

Kodable 是 iPad 上的一款免费的编程应用程序。它的口号是“让孩子在学会阅读之前学习代码”,这体现在它是通过有趣的游戏来帮助孩子学习编程。Kodable 是特别为 5 岁和 5 岁以上的孩子量身设计的,让他们能够在玩游戏的同时学习编程指令。Kodable 有 3 个等级的编程学习方案,包含了幼儿园到 2 年级课程、3 年级到 5 年级课程以及 6 年级到 12 年级的课程。

既然是免费的,那就更要试试了,总比在ipad上看电影玩游戏好吧。王颢老师建议:对于这类APP,可以下载下来玩玩,毕竟国外和国内的高端学校已经把ipad当成课堂必备。当大多数家长还在犹豫是否让孩子玩iPad时,别人已经享受它的便利,岂不悲哉?

六、Stencyl

Stencyl 是一款快速、免费和方便的工具,它允许你通过拖拽和使用移动滑块的方式开发游戏,而不需要使用任何代码。当然你如果不喜欢移动滑块的形式,你也可以选择键入代码。Stencyl 拥有广泛的平台支持,使用 Stencyl 开发出来的游戏可以在 Android, iOS, Windows, Mac 和 Linux 上运行。

王颢老师听说这个用起来比较复杂,当然Scratch用的比较顺溜了,可以尝试玩玩,但是王颢老师还是建议专一,哈哈!

七、Waterbear

Waterbear 是一款方便和可免费使用的编程工具包 ,它能够让孩子通过拖拽的形式进行编程。Waterbear 是可视化的编程语言,这意味着在开始编程的时候不需要学习语法。孩子们可以创建一个新文件,查看创作示例并自己动手随意摆弄,由于每个元素都有详细描述,这使得跟着模仿起来会相当简单。

王颢老师访问官网,试用了下,感觉有点复杂,还是学学比较火的吧。

八、RoboMind

RoboMind 是一款用于儿童学习的编程工具,它使用自身的被称为 ROBO 的语言。RoboMind 的主要目标是实现机器人沿二维网格行走并执行简单的任务。通过使用 RoboMind,你的孩子可以学习基本的人工智能,甚至可以在真正的机器人套件如 LEGO Mindstorms NXT 2.0 上使用它。RoboMind 提供 30 天的免费试用。

这个就是机器人编程了,开始上手不建议用这种语言。王颢老师想知道这是不是某博的语言?

九、Hackety Hack

Hackety Hack 是一款简单易用的编程工具,它能够绝对胜任基础编程的教学。使用 Hackety Hack 的用户不需要任何的编程经验。它是基于 Ruby 编程语言,Ruby 常用于开发桌面应用程序和网站等项目。因此,使用 Hackety Hack 的鞋子工具来创建图形化界面会非常简单。

看见代码了没?王颢老师一看见代码就头大,曾经虐过我多少次啊!严重不推荐啊。

十、Tynker

Tynker 是一款在线编程学习系统,它的目的是为了激励孩子们将他们的创意转化为游戏、项目和动画故事,并将他们的应用程序在网络上进行传播。Tynker 使用简单的可视化编程语言,不需要编程语法,而只需要将代码块组合起来就可以创建项目。当你支付一笔费用后,你可以获得它的终身访问权,并能够获得他们提供的在线课程、智力游戏集和夏令营等服务。

王颢老师都要免费分享编程课程,还报国外课程干嘛?当然土豪请随意!在查资料的过程中看到,这个公司的创始人比较奇葩,开公司、融资、上市最后倒闭,也算是经历丰富。

王颢老师经常说:语言不在于多,而在于精,要是谁上来推荐C语言,我上去就扇他一耳光。王颢老师学了几年都不敢说掌握,何况没有任何计算机基础的孩子!我可是费了很久的时间来选择,从使用人数,受欢迎程度,资料是否丰富,以后是否可以扩展到机器人编程上,每个细节都考虑了。知道王颢老师为什么这么累吗?太细心啦!!!

对了我整理了154个简单有趣的科学小实验,不用专门购买实验材料,在家里就可以做的。文章里只是其中的一个,可以找我要。我还整理了1000部有声绘本,也可以分享给你们。

我是王颢,儿童科学小实验专家,微信&QQ(7572320),敲门暗号:简书。聚焦儿童科学启蒙,提升孩子动手能力,陪伴孩子在互动交流中快乐成长,欢迎各位家长和老师交流!

本文首发王颢老师的个人博客《王颢》,欢迎大家交流学习!

MongoDB 管理工具: Rockmongo

RockMongo是PHP5写的一个MongoDB管理工具。
通过 Rockmongo 你可以管理 MongoDB服务,数据库,集合,文档,索引等等。

它提供了非常人性化的操作。类似 phpMyAdmin(PHP开发的MySql管理工具)。

Rockmongo 下载地址:http://rockmongo.com/downloads

rockmongo


简介

主要特征:

  • 使用宽松的New BSD License协议
  • 速度快,安装简单
  • 支持多语言(目前提供中文、英文、日文、巴西葡萄牙语、法语、德语、俄语、意大利语)
  • 系统
    • 可以配置多个主机,每个主机可以有多个管理员
    • 需要管理员密码才能登入操作,确保数据库的安全性
  • 服务器
    • 服务器信息 (WEB服务器, PHP, PHP.ini相关指令 ...)
    • 状态
    • 数据库信息
  • 数据库
    • 查询,创建和删除
    • 执行命令和Javascript代码
    • 统计信息
  • 集合(相当于表)
    • 强大的查询工具
    • 读数据,写数据,更改数据,复制数据,删除数据
    • 查询、创建和删除索引
    • 清空数据
    • 批量删除和更改数据
    • 统计信息
  • GridFS
    • 查看分块
    • 下载文件

安装

需求

  • 一个能运行PHP的Web服务器,比如Apache Httpd, Nginx ...
  • PHP - 需要PHP v5.1.6或更高版本,需要支持SESSION
    • 为了能连接MongoDB,你需要安装php_mongo扩展

快速安装

  • 下载安装包
  • 解压到你的网站目录下
  • 用编辑器打开config.php,修改host, port, admins等参数
  • 在浏览器中访问index.php,比如说:http://localhost/rockmongo/index.php
  • 使用用户名和密码登录,默认为"admin"和"admin"
  • 开始玩转MongoDB!

参考文章:http://rockmongo.com/wiki/introduction?lang=zh_cn

方便的安装方法:

docker 镜像安装     https://hub.docker.com/r/anapsix/rockmongo/

docker run --name rockmongo -d -p 5000:5000  --add-host zookeeper:192.168.128.189 -v

/export/data/rockmongo/config.php:/rockmongo/config.php docker.xb.sinosig.com:443/anapsix/rockmongo:xb && docker

logs -f rockmongo

 

Gossip 协议

背景

Gossip 算法又被称为反熵(Anti-Entropy),熵是物理学上的一个概念,代表杂乱无章,而反熵就是在杂乱无章中寻求一致,这充分说明了 Gossip 的特点:在一个有界网络中,每个节点都随机地与其他节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。每个节点可能知道所有其他节点,也可能仅知道几个邻居节点,只要这些节可以通过网络连通,最终他们的状态都是一致的,当然这也是疫情传播的特点。
简单的描述下这个协议,首先要传播谣言就要有种子节点。种子节点每秒都会随机向其他节点发送自己所拥有的节点列表,以及需要传播的消息。任何新加入的节点,就在这种传播方式下很快地被全网所知道。这个协议的神奇就在于它从设计开始就没想到信息一定要传递给所有的节点,但是随着时间的增长,在最终的某一时刻,全网会得到相同的信息。当然这个时刻可能仅仅存在于理论,永远不可达。

实现

gossip 协议有多种实现,这里说一个例子当节点启动时,读配置文件,然后向一个 seed 发送信息,进行信息同步,然后开始没秒都随机选择一个 seed 节点来同步信息
1、随机取一个当前活着的节点,并向它发送同步请求
2、向随机一台不可达的机器发送同步请求
3、如果第一步中所选择的节点不是 seed,或者当前活着的节点数少于 seed 数,则向随意一台 seed 发送同步请求

应用

Cassandra
Cassandra 主要是使用 Gossip 完成三方面的功能:
失败检测
动态负载均衡
去中心化的弹性扩展
Consul

参考数据节选到这里
Gossip算法因为Cassandra而名声大噪,Gossip看似简单,但要真正弄清楚其本质远没看起来那么容易。为了寻求Gossip的本质,下面的内容主要参考Gossip的原始论文:<<Efficient Reconciliation and Flow Control for Anti-Entropy Protocols>>。

 

1. Gossip背景

Gossip算法如其名,灵感来自办公室八卦,只要一个人八卦一下,在有限的时间内所有的人都会知道该八卦的信息,这种方式也与病毒传播类似,因此Gossip有众多的别名“闲话算法”、“疫情传播算法”、“病毒感染算法”、“谣言传播算法”。

但Gossip并不是一个新东西,之前的泛洪查找、路由算法都归属于这个范畴,不同的是Gossip给这类算法提供了明确的语义、具体实施方法及收敛性证明。

2. Gossip特点

Gossip算法又被称为反熵(Anti-Entropy),熵是物理学上的一个概念,代表杂乱无章,而反熵就是在杂乱无章中寻求一致,这充分说明了Gossip的特点:在一个有界网络中,每个节点都随机地与其他节点通信,经过一番杂乱无章的通信,最终所有节点的状态都会达成一致。每个节点可能知道所有其他节点,也可能仅知道几个邻居节点,只要这些节可以通过网络连通,最终他们的状态都是一致的,当然这也是疫情传播的特点。

要注意到的一点是,即使有的节点因宕机而重启,有新节点加入,但经过一段时间后,这些节点的状态也会与其他节点达成一致,也就是说,Gossip天然具有分布式容错的优点。

3. Gossip本质

Gossip是一个带冗余的容错算法,更进一步,Gossip是一个最终一致性算法。虽然无法保证在某个时刻所有节点状态一致,但可以保证在”最终“所有节点一致,”最终“是一个现实中存在,但理论上无法证明的时间点。

因为Gossip不要求节点知道所有其他节点,因此又具有去中心化的特点,节点之间完全对等,不需要任何的中心节点。实际上Gossip可以用于众多能接受“最终一致性”的领域:失败检测、路由同步、Pub/Sub、动态负载均衡。

但Gossip的缺点也很明显,冗余通信会对网路带宽、CUP资源造成很大的负载,而这些负载又受限于通信频率,该频率又影响着算法收敛的速度,后面我们会讲在各种场合下的优化方法。

4. Gossip节点的通信方式及收敛性

根据原论文,两个节点(A、B)之间存在三种通信方式:

  • push: A节点将数据(key,value,version)及对应的版本号推送给B节点,B节点更新A中比自己新的数据
  • pull:A仅将数据key,version推送给B,B将本地比A新的数据(Key,value,version)推送给A,A更新本地
  • push/pull:与pull类似,只是多了一步,A再将本地比B新的数据推送给B,B更新本地

如果把两个节点数据同步一次定义为一个周期,则在一个周期内,push需通信1次,pull需2次,push/pull则需3次,从效果上来讲,push/pull最好,理论上一个周期内可以使两个节点完全一致。直观上也感觉,push/pull的收敛速度是最快的。

假设每个节点通信周期都能选择(感染)一个新节点,则Gossip算法退化为一个二分查找过程,每个周期构成一个平衡二叉树,收敛速度为O(n2 ),对应的时间开销则为O(logn )。这也是Gossip理论上最优的收敛速度。但在实际情况中最优收敛速度是很难达到的,假设某个节点在第i个周期被感染的概率为pi ,第i+1个周期被感染的概率为pi+1 ,则pull的方式:

pull

而push为:

push

显然pull的收敛速度大于push,而每个节点在每个周期被感染的概率都是固定的p(0<p<1),因此Gossip算法是基于p的平方收敛,也成为概率收敛,这在众多的一致性算法中是非常独特的。

个Gossip的节点的工作方式又分两种:

  • Anti-Entropy(反熵):以固定的概率传播所有的数据
  • Rumor-Mongering(谣言传播):仅传播新到达的数据

Anti-Entropy模式有完全的容错性,但有较大的网络、CPU负载;Rumor-Mongering模式有较小的网络、CPU负载,但必须为数据定义”最新“的边界,并且难以保证完全容错,对失败重启且超过”最新“期限的节点,无法保证最终一致性,或需要引入额外的机制处理不一致性。我们后续着重讨论Anti-Entropy模式的优化。

5. Anti-Entropy的协调机制

协调机制是讨论在每次2个节点通信时,如何交换数据能达到最快的一致性,也即消除两个节点的不一致性。上面所讲的push、pull等是通信方式,协调是在通信方式下的数据交换机制。协调所面临的最大问题是,因为受限于网络负载,不可能每次都把一个节点上的数据发送给另外一个节点,也即每个Gossip的消息大小都有上限。在有限的空间上有效率地交换所有的消息是协调要解决的主要问题。

在讨论之前先声明几个概念:

  • 令N = {p,q,s,...}为需要gossip通信的server集合,有界大小
  • 令(p1,p2,...)是宿主在节点p上的数据,其中数据有(key,value,version)构成,q的规则与p类似。

为了保证一致性,规定数据的value及version只有宿主节点才能修改,其他节点只能间接通过Gossip协议来请求数据对应的宿主节点修改。

5.1 精确协调(Precise Reconciliation)

精确协调希望在每次通信周期内都非常准确地消除双方的不一致性,具体表现为相互发送对方需要更新的数据,因为每个节点都在并发与多个节点通信,理论上精确协调很难做到。精确协调需要给每个数据项独立地维护自己的version,在每次交互是把所有的(key,value,version)发送到目标进行比对,从而找出双方不同之处从而更新。但因为Gossip消息存在大小限制,因此每次选择发送哪些数据就成了问题。当然可以随机选择一部分数据,也可确定性的选择数据。对确定性的选择而言,可以有最老优先(根据版本)和最新优先两种,最老优先会优先更新版本最新的数据,而最新更新正好相反,这样会造成老数据始终得不到机会更新,也即饥饿。

当然,开发这也可根据业务场景构造自己的选择算法,但始终都无法避免消息量过多的问题。

5.2 整体协调(Scuttlebutt Reconciliation)

整体协调与精确协调不同之处是,整体协调不是为每个数据都维护单独的版本号,而是为每个节点上的宿主数据维护统一的version。比如节点P会为(p1,p2,...)维护一个一致的全局version,相当于把所有的宿主数据看作一个整体,当与其他节点进行比较时,只需必须这些宿主数据的最高version,如果最高version相同说明这部分数据全部一致,否则再进行精确协调。

整体协调对数据的选择也有两种方法:

  • 广度优先:根据整体version大小排序,也称为公平选择
  • 深度优先:根据包含数据多少的排序,也称为非公平选择。因为后者更有实用价值,所以原论文更鼓励后者

6. Cassandra中的实现

经过验证,Cassandra实现了基于整体协调的push/push模式,有几个组件:

三条消息分别对应push/pull的三个阶段:

  • GossipDigitsMessage
  • GossipDigitsAckMessage
  • GossipDigitsAck2Message

还有三种状态:

  • EndpointState:维护宿主数据的全局version,并封装了HeartBeat和ApplicationState
  • HeartBeat:心跳信息
  • ApplicationState:系统负载信息(磁盘使用率)

Cassandra主要是使用Gossip完成三方面的功能:

  • 失败检测
  • 动态负载均衡
  • 去中心化的弹性扩展

7. 总结

Gossip是一种去中心化、容错而又最终一致性的绝妙算法,其收敛性不但得到证明还具有指数级的收敛速度。使用Gossip的系统可以很容易的把Server扩展到更多的节点,满足弹性扩展轻而易举。

唯一的缺点是收敛是最终一致性,不使用那些强一致性的场景,比如2pc。

cassandra学习笔记–安装篇

Cassandra简介(注:该段介绍来自baidu百科)

Cassandra是一个混合型的非关系的数据库,类似于Google的BigTable。其主要功能比Dynomite(分布式的Key-Value存储系统)更丰富,但支持度却不如文档存储MongoDB(介于关系数据库和非关系数据库之间的开源产品,是非关系数据库当中功能最丰富,最像关系数据库的。支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。)Cassandra最初由Facebook开发,后转变成了开源项目。它是一个网络社交云计算方面理想的数据库。以Amazon专有的完全分布式的Dynamo为基础,结合了Google BigTable基于列族(Column Family)的数据模型。P2P去中心化的存储。很多方面都可以称之为Dynamo 2.0。

    功能

Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra 的一个写操作,会被复制到其他节点上去,对Cassandra的读操作,也会被路由到某个节点上面去读取。对于一个Cassandra群集来说,扩展性能是比较简单的事情,只管在群集里面添加节点就可以了。

这里有很多理由来选择Cassandra用于您的网站。和其他数据库比较,有三个突出特点:

    模式灵活 :使用Cassandra,像文档存储,你不必提前解决记录中的字段。你可以在系统运行时随意的添加或移除字段。这是一个惊人的效率提升,特别是在大型部署上。

    真正的可扩展性 :Cassandra是纯粹意义上的水平扩展。为给集群添加更多容量,可以指向另一台电脑。你不必重启任何进程,改变应用查询,或手动迁移任何数据。

    多数据中心识别 :你可以调整你的节点布局来避免某一个数据中心起火,一个备用的数据中心将至少有每条记录的完全复制。

 

一些使Cassandra提高竞争力的其他功能:

        范围查询 :如果你不喜欢全部的键值查询,则可以设置键的范围来查询。

        列表数据结构 :在混合模式可以将超级列添加到5维。对于每个用户的索引,这是非常方便的。

        分布式写操作 :有可以在任何地方任何时间集中读或写任何数据。并且不会有任何单点失败。

        应用客户:twitter、facebook等

Cassandra安装:

        第一步: 下载Cassandra   http://cassandra.apache.org/

第二步:解压缩与配置

将压缩包解压后复制你想安装的目录下,这里我安装在D:/apache-cassandra-0.6.1/目录中

安装目录

打开conf文件夹,可以对下面的相关配置文件进行配置,也可以使用默认.

你可以根据自己需要更改日志、数据库存放目录等参数

1) 修改conf目录下的log4j.properties文件:
log4j.appender.R.File=D:/apache-cassandra-0.6.1/logs

2) 修改conf目录下的storage-conf.xml文件:

<CommitLogDirectory>D:/apache-cassandra-0.6.1/commitlog</CommitLogDirectory>
<DataFileDirectories>
<DataFileDirectory>D:/apache-cassandra-0.6.1/data</DataFileDirectory>
</DataFileDirectories>

第三步:环境变量的配置

1)如果你的机子没有安装Java,请先下载并配置java的环境变量

2)设置环境变量"我的电脑"--"高级"选项卡--"环境变量"--"系统变量--新增",根据自己cassandra的位置来设置系统变量的值
                      cassandra 安装在:D:/apache-cassandra-0.6.1

canssadra_home 

        3)免重启激活环境变量
  在cmd中键入命令 " set Cassandra_Home=任意字符",这样环境变量可以在不重启的情况下被激活了。

为了确认是否被激活,重新开启新的cmd窗口,记住,一定要新开cmd才可以查看到被激活的环境变量。
你可以在新的cmd窗口中输入"echo %Cassandra_Home%"输出环境变量的值,我们会发现,可以获取到我们设置的值。

                     环境变量已性效

每四步: 正式的启动Cassandra服务

同样打开cmd窗口,在cmd窗口中执行D:/apache-cassandra-0.6.1/bin下面的cassandra.bat启动cassandra服务

成功界面

                   出现上面的图后表示服务启动成功了,记住,这个cmd的窗口不要关闭,关闭了好像服务就被一起关闭了,接下来客端的连接好像就不行了。

第五步:客户端的连接
    服务启动成功之后,cassandra里面默认有一个测试数据库,访问的方式是在cmd窗口中执行D:/apache-cassandra-0.6.1/bin下面的cassandra-cli.bat批处理文件,然后出现cassandra提示符,在提示符后面输入connect localhost/9160就可以连上默认的数据库。下图是连接成功后的界面。

客户端连接成功

                   再接着我们试着插入一条新记录,并读出这条记录的值。
插入的命令是"set"关键字
在命令提示符下输入

                                        " set Keyspace1.Standard1['jsmith']['first']" = 'john'
                   如果提示"Value inserted"表示插入成功。
同样我们把插入的值读出来,使用的关键字是"get"
“get Keyspace1.Standard1['jsmith']”

                  如图,我们把刚才插入的数据给读了出来。OK,就介绍到这。下面的东西自己也在摸索。学习中……

插入数据与查询数据

其他:cassandra默认使用8080端口,在bin目录下cassandra.bat文件中我们找到 -Dcom.sun.management.jmxremote.port=8080^,如果在你的机子上没有和8080冲突的东西的话,那你可以保留默认的8080,但很多时候会有冲突,比如oracle,tomcat等等,这时候就需要修改下。

 

Apache Cassandra是一套开源分布式Key-Value存储系统。它最初由Facebook开发,用于储存特别大的数据。

主要特性:分布式、基于column的结构化、高伸展性

Cassandra的主要特点就是它不是一个数据库,而是由一堆数据库节点共同构成的一个分布式网络服务,对Cassandra 的一个写操作,会被复制到其他节点上去,对Cassandra的读操作,也会被路由到某个节点上面去读取。对于一个Cassandra群集来说,扩展性能 是比较简单的事情,只管在群集里面添加节点就可以了。

Cassandra是一个混合型的非关系的数据库,类似于Google的BigTable。其主要功能比 Dynomite(分布式的Key-Value存 储系统)更丰富,但支持度却不如文档存储MongoDB(介于关系数据库和非关系数据库之间的开源产品,是非关系数据库当中功能最丰富,最像关系数据库 的。支持的数据结构非常松散,是类似json的bjson格式,因此可以存储比较复杂的数据类型。)Cassandra最初由Facebook开发,后转变成了开源项目。它是一个网络社交云计算方面理想的数据库。以Amazon专有的完全分布式的Dynamo为基础,结合了Google BigTable基于列族(Column Family)的数据模型。P2P去中心化的存储。很多方面都可以称之为Dynamo 2.0。

和其他数据库比较,有几个突出特点:

模式灵活 :使用Cassandra,像文档存储,你不必提前解决记录中的字段。你可以在系统运行时随意的添加或移除字段。这是一个惊人的效率提升,特别是在大型部署上。
真正的可扩展性 :Cassandra是纯粹意义上的水平扩展。为给集群添加更多容量,可以指向另一台电脑。你不必重启任何进程,改变应用查询,或手动迁移任何数据。
多数据中心识别 :你可以调整你的节点布局来避免某一个数据中心起火,一个备用的数据中心将至少有每条记录的完全复制。

Cassandra 中数据存储策略:

1. CommitLog:主要记录下客户端提交过来的数据以及操作。这个数据将被持久化到磁盘中,以便数据没有被持久化到磁盘时可以用来恢复。数据库中的commit log 分为 undo-log, redo-log 以及 undo-redo-log 三类,由于 cassandra采用时间戳识别新老数据而不会覆盖已有的数据,所以无须使用 undo 操作,因此它的 commit log 使用的是 redo log。
2. Memtable:用户写的数据在内存中的形式,Memtable中的数据是按照key排序好的,Memtable是一种内存结构,满足一定条件后批量刷新(flush)到磁盘上。其实还有另外一种形式是 BinaryMemtable 这个格式目前 Cassandra 并没有使用。
3. SSTable:数据被持久化到磁盘,这又分为 Data、Index 和 Filter 三种数据格式。SSTable一旦完成写入,就不可变更,只能读取。SSTable是不可修改的,且一般情况下一个CF可能会对应多个SSTable,这样,当用户检索数据时,如果每个SSTable均扫描一遍,将大大增加工作量。Cassandra为了减少没有必要的SSTable扫描,使用了BloomFilter,即通过多个hash函数将key映射到一个位图中,来快速判断这个key属于哪个SSTable。为了减少大量SSTable带来的开销,Cassandra会定期进行compaction,简单的说,compaction就是将同一个CF的多个SSTable合并成一个SSTable。

Cassandra 中数据分区策略:

将key/value按照key存放到不同的节点上。Partitioner会按照某种策略给每个cassandra节点分配一个token,每个key/value进行某种计算后,将被分配到器对应的节点上。

提供了以下几个分布策略:

org.apache.cassandra.dht.RandomPartitioner:

将key/value按照(key的)md5值均匀的存放到各个节点上。由于key是无序的,所有该策略无法支持针对Key的范围查询。

org.apache.cassandra.dht.ByteOrderedPartitioner(BOP):

将key/value按照key(byte)排序后存放到各个节点上。该Partitioner允许用户按照key的顺序扫描数据。该方法可能导致负载不均衡。

org.apache.cassandra.dht.OrderPreservingPartitioner:

该策略是一种过时的BOP,仅支持key为UTF8编码的字符串。

org.apache.cassandra.dht.CollatingOrderPreservingPartitioner:

该策略支持在EN或者US环境下的key排序方式。

Cassandra 中备份策略:

为了保证可靠性,一般要将数据写N份,其中一份写在其对应的节点上(由数据分片策略决定),另外N-1份如何存放,需要有相应的备份策略。

SimpleStrategy (以前称为RackUnawareStrategy,对应org.apache.cassandra.locator.RackUnawareStrategy):

不考虑数据中心,将Token按照从小到大的顺序,从第一个Token位置处依次取N个节点作为副本。

OldNetworkTopologyStrategy (以前称为RackAwareStrategy,对应org.apache.cassandra.locator.RackAwareStrategy):

考虑数据中心,首先,在primary Token所在的数据中心的不同rack上存储N-1份数据,然后在另外一个不同数据中心的节点存储一份数据。该策略特别适合多个数据中心的应用场景,这样可以牺牲部分性能(数据延迟)的前提下,提高系统可靠性。

NetworkTopologyStrategy (以前称为DatacenterShardStrategy,对应org.apache.cassandra.locator.DataCenterShardStrategy):

这需要复制策略属性文件,在该文件中定义在每个数据中心的副本数量。在各数据中心副本数量的总和应等于Keyspace的副本数量。

Cassandra 中网络拓扑策略:

主要用于计算不同host的相对距离,进而告诉Cassandra你的网络拓扑结构,以便更高效地对用户请求进行路由。

org.apache.cassandra.locator.SimpleSnitch:

将不同host逻辑上的距离(cassandra ring)作为他们之间的相对距离。

org.apache.cassandra.locator.RackInferringSnitch:

相对距离是由rack和data center决定的,分别对应ip的第3和第2个八位组。即,如果两个节点的ip的前3个八位组相同,则认为它们在同一个rack(同一个rack中不同节点,距离相同);如果两个节点的ip的前两个八位组相同,则认为它们在同一个数据中心(同一个data center中不同节点,距离相同)。

org.apache.cassandra.locator.PropertyFileSnitch:

相对距离是由rack和data center决定的,且它们是在配置文件cassandra-topology.properties中设置的。

Cassandra 中一致性策略:

Cassandra采用了最终一致性。最终一致性是指分布式系统中的一个数据对象的多个副本尽管在短时间内可能出现不一致,但是经过一段时间之后,这些副本最终会达到一致。

Cassandra 的一个特性是可以让用户指定每个读/插入/删除操作的一致性级别(consistency level)。Casssandra API 目前支持以下几种一致性级别:

ZERO:只对插入或者删除操作有意义。负责执行操作的节点把该修改发送给所有的备份节点,但是不会等待任何一个节点回复确认,因此不能保证任何的一致性。

ONE:对于插入或者删除操作,执行节点保证该修改已经写到一个存储节点的 commit log 和 Memtable 中;对于读操作,执行节点在获得一个存储节点上的数据之后立即返回结果。

QUORUM:假设该数据对象的备份节点数目为 n。对于插入或者删除操作,保证至少写到 n/2+1 个存储节点上;对于读操作,向 n/2+1 个存储节点查询,并返回时间戳最新的数据。

ALL:对于插入或者删除操作,执行节点保证n(n为replication factor)个节点插入或者删除成功后才向client返回成功确认消息,任何一个节点没有成功,该操作均失败;对于读操作,会向n个节点查询,返回时间戳最新的数据,同样,如果某个节点没有返回数据,则认为读失败。

Cassandra默认的读写模式W(QUORUM)/R(QUORUM),事实上,只要保证W+R>N(N为副本数),即写的节点和读的节点重叠,则是强一致性. 如果W+R<=N ,则是弱一致性.(其中,W是写节点数目,R是读节点数目)。

Cassandra 通过4个技术来维护数据的最终一致性,分别为逆熵(Anti-Entropy),读修复(Read Repair),提示移交(Hinted Handoff)和分布式删除。

(1) 逆熵

这是一种备份之间的同步机制。节点之间定期互相检查数据对象的一致性,这里采用的检查不一致的方法是 Merkle Tree;

(2) 读修复

客户端读取某个对象的时候,触发对该对象的一致性检查;

举例:读取Key A的数据时,系统会读取Key A的所有数据副本,如果发现有不一致,则进行一致性修复。

如果读一致性要求为ONE,会立即返回离客户端最近的一份数据副本。然后会在后台执行Read Repair。这意味着第一次读取到的数据可能不是最新的数据;如果读一致性要求为QUORUM,则会在读取超过半数的一致性的副本后返回一份副本给客户端,剩余节点的一致性检查和修复则在后台执行;如果读一致性要求高(ALL),则只有Read Repair完成后才能返回一致性的一份数据副本给客户端。可见,该机制有利于减少最终一致的时间窗口。

(3) 提示移交

对写操作,如果其中一个目标节点不在线,先将该对象中继到另一个节点上,中继节点等目标节点上线再把对象给它;

举例:Key A按照规则首要写入节点为N1,然后复制到N2。假如N1宕机,如果写入N2能满足ConsistencyLevel要求,则Key A对应的RowMutation将封装一个带hint信息的头部(包含了目标为N1的信息),然后随机写入一个节点N3,此副本不可读。同时正常复制一份数据到N2,此副本可以提供读。如果写N2不满足写一致性要求,则写会失败。 等到N1恢复后,原本应该写入N1的带hint头的信息将重新写回N1。

(4) 分布式删除

单机删除非常简单,只需要把数据直接从磁盘上去掉即可,而对于分布式,则不同,分布式删除的难点在于:如果某对象的一个备份节点 A 当前不在线,而其他备份节点删除了该对象,那么等 A 再次上线时,它并不知道该数据已被删除,所以会尝试恢复其他备份节点上的这个对象,这使得删除操作无效。Cassandra 的解决方案是:本地并不立即删除一个数据对象,而是给该对象标记一个hint,定期对标记了hint的对象进行垃圾回收。在垃圾回收之前,hint一直存在,这使得其他节点可以有机会由其他几个一致性保证机制得到这个hint。Cassandra 通过将删除操作转化为一个插入操作,巧妙地解决了这个问题。

Cassandra引入的是轻量级事务处理机制,或者说是通过CAS(Compare And Set)来处理或满足最终的一致性。比如在INSERT、UPDATE中使用IF语义来调用这种轻量级事务:

INSERT INTO customer_account (customerID, customer_email) 
VALUES (‘LauraS’, ‘lauras@gmail.com’)
IF NOT EXISTS;
UPDATE customer_account
SET    customer_email='laurass@gmail.com'
IF     customer_email='lauras@gmail.com';

软件企业从Subversion迁移到Git 真的准备好了吗

除了人,软件公司最宝贵的就是代码了,这些代码大多储存在Subversion(以下简称”SVN”)这样开源的版本控制系统(VCS)中。代码是容易修改和变更的,因此,代码的备份、历史追踪、协同编辑等任务同样需要版本控制系统完成。从最早本地VCS系统RCS、1990年CVS、2000年SVN,到如今开源世界风头正健的Git,同语言编辑工具一样,SVN、Git都是程序员的必备利器。随着GitHub的流行,很多软件企业开始计划转向Git,但是企业真的准备好了吗?

从SVN到Git,不仅仅是工具的替换,还有基于其上的工具和一些管理流程的变化。笔者建议:软件企业需要评估自己当前的状态和企业文化,认真考虑商业目标,谨慎迁移。我们不妨从以下几点来探讨一下。

陡峭的学习曲线

对于采用SVN进行管理的企业,Git相对复杂,开发工程师的学习曲线并不平缓。

Git的命令分为高层和底层,常用的高层命令约有30多个,与SVN近似。这些操作不能继承SVN的经验,因此工程师需要重新学习branch、merge、reset、rebase、revert、pull、fetch等操作命令,需要重新了解哈希值格式的版本号,并用它来进行检出、比较等。

对于较多使用word、ppt、excel、图片、IDE等工具的人员来说,从类似FTP的SVN转向Git ,学习过程会比较痛苦。

缺少角色授权和文件级访问控制

Git作为开源自由原教旨主义项目,它没有对版本库的浏览和修改做任何的权限限制。Git的创始人Linus Torvalds 也曾说:“不要让权限成为政治的理由,Git没有权限控制。”

由于缺少角色授权,因此在组织结构管理上比较困难。实际操作中,一个Git仓库用来实现一个项目,大型项目可能需要许多Git仓库配合实现。在SVN中不同项目在不同目录中,通过角色授权完成组织结构的规划。

实现商业目标的软件企业显然需要文档或代码的访问授权和控制,目前Git本身是不支持的,需要集成第三方工具实现访问控制。

有限的目录检出功能

SVN是一个中心仓库和众多客户端目录的关系,因此,SVN用户都熟悉工作在某个目录上,在不同的工作计算机上,检出目录就可以编辑。然而,Git是一个中心仓库和众多客户端仓库的关系,你必须工作在整个仓库上,虽然在Git1.7版本后支持了类似目录检出的功能,但仍要先检出整个仓库。软件企业的工程师常同时在多个项目中工作,如果修改一点东西就需要克隆仓库,对故障响应将有影响。

浪费已投入的开发成本

软件开发生命周期管理工具的基础是版本控制系统,各商业软件开发管理平台都是基于自主研发的版本控制系统,在此基础上扩展到项目管理、文档管理、代码评审、发布部署、缺陷管理等。基于SVN的开源或自主研发的管理工具非常成熟多样。迁移到Git,则完全浪费了投入到SVN管理工具的开发成本。

图形化工具及接口不够强

虽然Git的图形工具正在增多,但在Windows下还需要等待这些开源工具增强功能。同时,Git的接口待加强,与众多工具集成待完善,这些都是需要时间来解决。

目前很多人倡导的Git的优点并非不可替代

Git速度快,但是SVN使用用廉价的高性能主机同样可以提升速度;Git无需网路也可以工作,但当前稳固的网络基础环境和多样的接入方式,让SVN并不担心网络问题。另外Git方便地处理分支的特性,如果通过控制开发节奏,增加评审,减少分支数量,就可以让分支合并更简单快键,开发会更有效率,SVN也可以更好地管理分支。 SVN的1.7版本以不兼容旧版客户端的代价新增和改进了很多功能,开始向Git靠拢,这也使SVN具备Git的特性。

鉴于以上分享的几个基本点,建议企业谨慎迁移。

笔者对某些场景的命令进行了比较,下表是在Git-1.7 和SVN-1.6上测试的,目的是为了说明SVN的操作经验在Git上不能直接套用,当然Git也有许多独特的优秀功能。

场景SVNGit
操作动作追踪所有的操作均作为一次提交,并分配版本号,可追踪可以撤销某次提交、合并的动作,好像没有发生一样
引用公共库用链接目录实现
$svn propset svn:externals < module name> < repository_url>
Git 先克隆仓库,再用子模块方式实现
$git clone < repository_url> < directory>
$git submodule add < repository_url>
在本地检出目录用检出功能实现
$ svn co < repository_url> < directory>
需要先克隆仓库,激活目录检出功能, 通过配置需要保留的目录实现
$git clone < repository_url> < directory>
$cd < directory>
$git config core.sparsecheckout true
$echo < directory> >> .git/info/sparse-checkout
$git read-tree -m -u HEAD
新增文件到中心仓库用提交功能实现
$svn add < file>
$svn commit –m “new file”
提交后,需要推送到中心仓库
$git add < file>
$git commit –m “new file”
$git push origin

作者简介

李新,新浪产品部高级配置管理工程师,有丰富的软件流程方面的经验。

 

来源: http://www.infoq.com/cn/news/2012/09/is-git-ready-to-replace-svn