第二十一周微职位

一、概述redis的应用场景、redis的架构及实现。python

1)Redis最为经常使用的数据类型主要有如下:linux

  • Stringios

  • Hashredis

  • List算法

  • Setsql

  • Sorted setmongodb

  • pub/sub数据库

  • Transactionsapi

在具体描述这几种数据类型以前,咱们先经过一张图了解下Redis内部内存管理中是如何描述这些不一样数据类型的:数组

wKiom1nYxUGgZBV5AABX0wZRsO8297.jpg

首先Redis内部使用一个redisObject对象来表示全部的key和value,redisObject最主要的信息如上图所示:

         type表明一个value对象具体是何种数据类型,

         encoding是不一样数据类型在redis内部的存储方式,

         好比:type=string表明value存储的是一个普通字符串,那么对应的encoding能够是raw或者是int,若是是int则表明实际redis内部是按数值型类存储和表示这个字符串的,固然前提是这个字符串自己能够用数值表示,好比:"123" "456"这样的字符串。

       这里须要特殊说明一下vm字段,只有打开了Redis的虚拟内存功能,此字段才会真正的分配内存,该功能默认是关闭状态的,该功能会在后面具体描述。经过上图咱们能够发现Redis使用redisObject来表示全部的key/value数据是比较浪费内存的,固然这些内存管理成本的付出主要也是为了给Redis不一样数据类型提供一个统一的管理接口,实际做者也提供了多种方法帮助咱们尽可能节省内存使用,咱们随后会具体讨论。

2)各类数据类型应用和实现方式

下面咱们先来逐一的分析下这7种数据类型的使用和内部实现方式:


String:


Strings 数据结构是简单的key-value类型,value其实不只是String,也能够是数字.

经常使用命令:  set,get,decr,incr,mget 等。

应用场景:String是最经常使用的一种数据类型,普通的key/ value 存储均可以归为此类.便可以彻底实现目前 Memcached 的功能,而且效率更高。还能够享受Redis的定时持久化,操做日志及 Replication等功能。除了提供与 Memcached 同样的get、set、incr、decr 等操做外,Redis还提供了下面一些操做:
获取字符串长度
往字符串append内容
设置和获取字符串的某一段内容
设置及获取字符串的某一位(bit)
批量设置一系列字符串的内容
实现方式:String在redis内部存储默认就是一个字符串,被redisObject所引用,当遇到incr,decr等操做时会转成数值型进行计算,此时redisObject的encoding字段为int。
Hash
经常使用命令:hget,hset,hgetall 等。
应用场景:在Memcached中,咱们常常将一些结构化的信息打包成HashMap,在客户端序列化后存储为一个字符串的值,好比用户的昵称、年龄、性别、积分等,这时候在须要修改其中某一项时,一般须要将全部值取出反序列化后,修改某一项的值,再序列化存储回去。这样不只增大了开销,也不适用于一些可能并发操做的场合(好比两个并发的操做都须要修改积分)。而Redis的Hash结构可使你像在数据库中Update一个属性同样只修改某一项属性值。
        咱们简单举个实例来描述下Hash的应用场景,好比咱们要存储一个用户信息对象数据,包含如下信息:
用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,若是用普通的key/value结构来存储,主要有如下2种存储方式:

wKioL1nYxh7jMoRAAACPM7HN4wk728.png


第一种方式将用户ID做为查找key,把其余信息封装成一个对象以序列化的方式存储,这种方式的缺点是,增长了序列化/反序列化的开销,而且在须要修改其中一项信息时,须要把整个对象取回,而且修改操做须要对并发进行保护,引入CAS等复杂问题。

wKioL1nYxnjCd_ZnAACJi3AOJMw966.png

第二种方法是这个用户信息对象有多少成员就存成多少个key-value对儿,用用户ID+对应属性的名称做为惟一标识来取得对应属性的值,虽然省去了序列化开销和并发问题,可是用户ID为重复存储,若是存在大量这样的数据,内存浪费仍是很是可观的。

那么Redis提供的Hash很好的解决了这个问题,Redis的Hash实际是内部存储的Value为一个HashMap,并提供了直接存取这个Map成员的接口,以下图:

wKioL1nYxsfCPihSAADCutfvfdU747.png

也就是说,Key仍然是用户ID, value是一个Map,这个Map的key是成员的属性名,value是属性值,这样对数据的修改和存取均可以直接经过其内部Map的Key(Redis里称内部Map的key为field), 也就是经过 key(用户ID) + field(属性标签) 就能够操做对应属性数据了,既不须要重复存储数据,也不会带来序列化和并发修改控制的问题。很好的解决了问题。

这里同时须要注意,Redis提供了接口(hgetall)能够直接取到所有的属性数据,可是若是内部Map的成员不少,那么涉及到遍历整个内部Map的操做,因为Redis单线程模型的缘故,这个遍历操做可能会比较耗时,而另其它客户端的请求彻底不响应,这点须要格外注意。

实现方式:

上面已经说到Redis Hash对应Value内部实际就是一个HashMap,实际这里会有2种不一样实现,这个Hash的成员比较少时Redis为了节省内存会采用相似一维数组的方式来紧凑存储,而不会采用真正的HashMap结构,对应的value redisObject的encoding为zipmap,当成员数量增大时会自动转成真正的HashMap,此时encoding为ht。


List


经常使用命令:lpush,rpush,lpop,rpop,lrange等。

应用场景:

Redis list的应用场景很是多,也是Redis最重要的数据结构之一,好比twitter的关注列表,粉丝列表等均可以用Redis的list结构来实现。

Lists 就是链表,相信略有数据结构知识的人都应该能理解其结构。使用Lists结构,咱们能够轻松地实现最新消息排行等功能。Lists的另外一个应用就是消息队列,
能够利用Lists的PUSH操做,将任务存在Lists中,而后工做线程再用POP操做将任务取出进行执行。Redis还提供了操做Lists中某一段的api,你能够直接查询,删除Lists中某一段的元素。

实现方式:

Redis list的实现为一个双向链表,便可以支持反向查找和遍历,更方便操做,不过带来了部分额外的内存开销,Redis内部的不少实现,包括发送缓冲队列等也都是用的这个数据结构。


Set


经常使用命令:

sadd,spop,smembers,sunion 等。

应用场景:

Redis set对外提供的功能与list相似是一个列表的功能,特殊之处在于set是能够自动排重的,当你须要存储一个列表数据,又不但愿出现重复数据时,set是一个很好的选择,而且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。

Sets 集合的概念就是一堆不重复值的组合。利用Redis提供的Sets数据结构,能够存储一些集合性的数据,好比在微博应用中,能够将一个用户全部的关注人存在一个集合中,将其全部粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操做,能够很是方便的实现如共同关注、共同喜爱、二度好友等功能,对上面的全部集合操做,你还可使用不一样的命令选择将结果返回给客户端仍是存集到一个新的集合中。

实现方式:

set 的内部实现是一个 value永远为null的HashMap,实际就是经过计算hash的方式来快速排重的,这也是set能提供判断一个成员是否在集合内的缘由。


Sorted Set


经常使用命令:

zadd,zrange,zrem,zcard等

使用场景:

Redis sorted set的使用场景与set相似,区别是set不是自动有序的,而sorted set能够经过用户额外提供一个优先级(score)的参数来为成员排序,而且是插入有序的,即自动排序。当你须要一个有序的而且不重复的集合列表,那么能够选择sorted set数据结构,好比twitter 的public timeline能够以发表时间做为score来存储,这样获取时就是自动按时间排好序的。

另外还能够用Sorted Sets来作带权重的队列,好比普通消息的score为1,重要消息的score为2,而后工做线程能够选择按score的倒序来获取工做任务。让重要的任务优先执行。

实现方式:

Redis sorted set的内部使用HashMap和跳跃表(SkipList)来保证数据的存储和有序,HashMap里放的是成员到score的映射,而跳跃表里存放的是全部的成员,排序依据是HashMap里存的score,使用跳跃表的结构能够得到比较高的查找效率,而且在实现上比较简单。



Pub/Sub

Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你能够设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,全部订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用做实时消息系统,好比普通的即时聊天,群聊等功能。



Transactions

谁说NoSQL都不支持事务,虽然Redis的Transactions提供的并非严格的ACID的事务(好比一串用EXEC提交执行的命令,在执行中服务器宕机,那么会有一部分命令执行了,剩下的没执行),可是这个Transactions仍是提供了基本的命令打包执行的功能(在服务器不出问题的状况下,能够保证一连串的命令是顺序在一块儿执行的,中间有会有其它客户端命令插进来执行)。Redis还提供了一个Watch功能,你能够对一个key进行Watch,而后再执行Transactions,在这过程当中,若是这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。


3)Redis实际应用场景

Redis在不少方面与其余数据库解决方案不一样:它使用内存提供主存储支持,而仅使用硬盘作持久性的存储;它的数据模型很是独特,用的是单线程。另外一个大区别在于,你能够在开发环境中使用Redis的功能,但却不须要转到Redis。

转向Redis固然也是可取的,许多开发者从一开始就把Redis做为首选数据库;但设想若是你的开发环境已经搭建好,应用已经在上面运行了,那么更换数据库框架显然不那么容易。另外在一些须要大容量数据集的应用,Redis也并不适合,由于它的数据集不会超过系统可用的内存。因此若是你有大数据应用,并且主要是读取访问模式,那么Redis并非正确的选择。

        然而我喜欢Redis的一点就是你能够把它融入到你的系统中来,这就可以解决不少问题,好比那些你现有的数据库处理起来感到缓慢的任务。这些你就能够经过Redis来进行优化,或者为应用建立些新的功能。在本文中,我就想探讨一些怎样将Redis加入到现有的环境中,并利用它的原语命令等功能来解决 传统环境中碰到的一些常见问题。在这些例子中,Redis都不是做为首选数据库。

(1)显示最新的项目列表

下面这个语句经常使用来显示最新项目,随着数据多了,查询毫无疑问会愈来愈慢。

SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10

在Web应用中,“列出最新的回复”之类的查询很是广泛,这一般会带来可扩展性问题。这使人沮丧,由于项目原本就是按这个顺序被建立的,但要输出这个顺序却不得不进行排序操做。

        相似的问题就能够用Redis来解决。好比说,咱们的一个Web应用想要列出用户贴出的最新20条评论。在最新的评论边上咱们有一个“显示所有”的连接,点击后就能够得到更多的评论。

        咱们假设数据库中的每条评论都有一个惟一的递增的ID字段。

        咱们可使用分页来制做主页和评论页,使用Redis的模板,每次新评论发表时,咱们会将它的ID添加到一个Redis列表:

LPUSH latest.comments <ID>

       咱们将列表裁剪为指定长度,所以Redis只须要保存最新的5000条评论:

       LTRIM latest.comments 0 5000 

      每次咱们须要获取最新评论的项目范围时,咱们调用一个函数来完成(使用伪代码):

FUNCTION get_latest_comments(start, num_items):  
    id_list = redis.lrange("latest.comments",start,start+num_items - 1)  
    IF id_list.length < num_items  
        id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")  
    END  
    RETURN id_list  
END

 这里咱们作的很简单。在Redis中咱们的最新ID使用了常驻缓存,这是一直更新的。可是咱们作了限制不能超过5000个ID,所以咱们的获取ID函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才须要去访问数据库。

        咱们的系统不会像传统方式那样“刷新”缓存,Redis实例中的信息永远是一致的。SQL数据库(或是硬盘上的其余类型数据库)只是在用户须要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。

(2)删除与过滤

      咱们可使用LREM来删除评论。若是删除操做很是少,另外一个选择是直接跳过评论条目的入口,报告说该评论已经不存在。

       有些时候你想要给不一样的列表附加上不一样的过滤器。若是过滤器的数量受到限制,你能够简单的为每一个不一样的过滤器使用不一样的Redis列表。毕竟每一个列表只有5000条项目,但Redis却可以使用很是少的内存来处理几百万条项目。

(3)排行榜相关

      另外一个很广泛的需求是各类数据库的数据并不是存储在内存中,所以在按得分排序以及实时更新这些几乎每秒钟都须要更新的功能上数据库的性能不够理想。

      典型的好比那些在线游戏的排行榜,好比一个Facebook的游戏,根据得分你一般想要:

         - 列出前100名高分选手

         - 列出某用户当前的全球排名

      这些操做对于Redis来讲小菜一碟,即便你有几百万个用户,每分钟都会有几百万个新的得分。

      模式是这样的,每次得到新得分时,咱们用这样的代码:

      ZADD leaderboard  <score>  <username> 

     你可能用userID来取代username,这取决于你是怎么设计的。

      获得前100名高分用户很简单:ZREVRANGE leaderboard 0 99。

      用户的全球排名也类似,只须要:ZRANK leaderboard <username>。

(4)按照用户投票和时间排序

      排行榜的一种常见变体模式就像Reddit或Hacker News用的那样,新闻按照相似下面的公式根据得分来排序:

       score = points / time^alpha 

      所以用户的投票会相应的把新闻挖出来,但时间会按照必定的指数将新闻埋下去。下面是咱们的模式,固然算法由你决定。

      模式是这样的,开始时先观察那些多是最新的项目,例如首页上的1000条新闻都是候选者,所以咱们先忽视掉其余的,这实现起来很简单。

      每次新的新闻贴上来后,咱们将ID添加到列表中,使用LPUSH + LTRIM,确保只取出最新的1000条项目。

      有一项后台任务获取这个列表,而且持续的计算这1000条新闻中每条新闻的最终得分。计算结果由ZADD命令按照新的顺序填充生成列表,老新闻则被清除。这里的关键思路是排序工做是由后台任务来完成的。

(5)处理过时项目

      另外一种经常使用的项目排序是按照时间排序。咱们使用unix时间做为得分便可。

      模式以下:

       - 每次有新项目添加到咱们的非Redis数据库时,咱们把它加入到排序集合中。这时咱们用的是时间属性,current_time和time_to_live。

       - 另外一项后台任务使用ZRANGE…SCORES查询排序集合,取出最新的10个项目。若是发现unix时间已通过期,则在数据库中删除条目。

(6)计数

       Redis是一个很好的计数器,这要感谢INCRBY和其余类似命令。

       我相信你曾许屡次想要给数据库加上新的计数器,用来获取统计或显示新信息,可是最后却因为写入敏感而不得不放弃它们。

       好了,如今使用Redis就不须要再担忧了。有了原子递增(atomic increment),你能够放心的加上各类计数,用GETSET重置,或者是让它们过时。

       例如这样操做:

         INCR user:<id> EXPIRE 

         user:<id> 60 

       你能够计算出最近用户在页面间停顿不超过60秒的页面浏览量,当计数达到好比20时,就能够显示出某些条幅提示,或是其它你想显示的东西。

(7)特定时间内的特定项目

        另外一项对于其余数据库很难,但Redis作起来却垂手可得的事就是统计在某段特色时间里有多少特定用户访问了某个特定资源。好比我想要知道某些特定的注册用户或IP地址,他们到底有多少访问了某篇文章。

      每次我得到一次新的页面浏览时我只须要这样作:

       SADD page:day1:<page_id> <user_id> 

      固然你可能想用unix时间替换day1,好比time()-(time()%3600*24)等等。

      想知道特定用户的数量吗?只须要使用SCARD page:day1:<page_id>。

       须要测试某个特定用户是否访问了这个页面?SISMEMBER page:day1:<page_id>。

(8)实时分析正在发生的状况,用于数据统计与防止垃圾邮件等

        咱们只作了几个例子,但若是你研究Redis的命令集,而且组合一下,就能得到大量的实时分析方法,有效并且很是省力。使用Redis原语命令,更容易实施垃圾邮件过滤系统或其余实时跟踪系统。

(9)Pub/Sub

       Redis的Pub/Sub很是很是简单,运行稳定而且快速。支持模式匹配,可以实时订阅与取消频道。

(10)队列

        你应该已经注意到像list push和list pop这样的Redis命令可以很方便的执行队列操做了,但能作的可不止这些:好比Redis还有list pop的变体命令,可以在列表为空时阻塞队列。

       现代的互联网应用大量地使用了消息队列(Messaging)。消息队列不只被用于系统内部组件之间的通讯,同时也被用于系统跟其它服务之间的交互。消息队列的使用能够增长系统的可扩展性、灵活性和用户体验。非基于消息队列的系统,其运行速度取决于系统中最慢的组件的速度(注:短板效应)。而基于消息队列能够将系统中各组件解除耦合,这样系统就再也不受最慢组件的束缚,各组件能够异步运行从而得以更快的速度完成各自的工做。

    此外,当服务器处在高并发操做的时候,好比频繁地写入日志文件。能够利用消息队列实现异步处理。从而实现高性能的并发操做。



二、搭建一套mongodb分布式集群系统。

目标:
搭建带有安全认证的mongodb集群准生产环境。
    一共3个shard,每个shard有3个replica set,replicat set采用primary、secondary、secondary方式。9个mongod实例,另外,3个config server,3个mongod实例,3个mongos实例。
        mongodb版本 3.2.9 社区版本
        Cores 4
        OS Name CentOS release 6.6 (Final)
        OS Version Linux version 2.6.32-504.3.3.el6.x86_64 RAM (MB) 3729
注意:关闭SELINUX注意:服务器时间同步,好比用ntpdate,能够暂时略过无论。
最后会有核武。MongoDB Ops Manager

服务器准备:
服务器-ip
192.168.3.73    
192.168.3.74    
192.168.3.75    
另外准备一台192.168.3.81用做MongoDB Ops Manager。
访问互通
好比在192.168.3.73机器上修改
vi /etc/hosts
192.168.3.73 73.dooioo.org
192.168.3.74 74.dooioo.org
192.168.3.75 75.dooioo.org
192.168.3.76 76.dooioo.org
192.168.3.81 81.dooioo.org
vi /etc/sysconfig/network
HOSTNAME=73.dooioo.org

即刻生效可使用在命令下执行便可,以下命令

hostname 73.dooioo.org

下载安装

登陆到192.168.3.73

$ cd /root
$ wget https://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.2.9.tgz
$ scp mongodb-linux-x86_64-rhel62-3.2.9.tgz root@192.168.3.74:/root
$ scp mongodb-linux-x86_64-rhel62-3.2.9.tgz root@192.168.3.75:/root
$ scp mongodb-linux-x86_64-rhel62-3.2.9.tgz root@192.168.3.76:/root
$ tar zxvf mongodb-linux-x86_64-rhel62-3.2.9.tgz

规划集群和分片

规划3个shard * 3个replicat set + 配置服务

shard rs name Primary Secondary Secondary port
fang-s-a a1 a2 a3 28111
fang-s-b b2 b1 b3 28112
fang-s-c c3 c1 c2 28113
fang-cs configserver1 configserver2 configserver3 28200

规划3个config server的mongod实例configserver一、configserver二、configserver3

hostname 实例
73.dooioo.org a1 b1 c1 configserver1
74.dooioo.org a2 b2 c2 configserver2
75.dooioo.org a3 b3 c3 configserver3

规划目录和配置文件

建立必要的目录和文件

#!/usr/bin/env bash
# 登陆到192.168.3.73
# 建立db目录 日志目录 mongod配置文件
mkdir -p /mongodb/a1
mkdir -p /home/log/mongodb/a1
mkdir -p /mongodb/b1
mkdir -p /home/log/mongodb/b1
mkdir -p /mongodb/c1
mkdir -p /home/log/mongodb/c1
 
mkdir -p /mongodb/configserver1
mkdir -p /home/log/mongodb/configserver1
 
touch /mongodb/mongod-a1-config.yml
touch /mongodb/mongod-b1-config.yml
touch /mongodb/mongod-c1-config.yml
touch /mongodb/mongod-configserver1.yml

# 登陆到192.168.3.74
mkdir -p /mongodb/a2
mkdir -p /home/log/mongodb/a2
mkdir -p /mongodb/b2
mkdir -p /home/log/mongodb/b2
mkdir -p /mongodb/c2
mkdir -p /home/log/mongodb/c2
 
mkdir -p /mongodb/configserver2
mkdir -p /home/log/mongodb/configserver2
 
touch /mongodb/mongod-a2-config.yml
touch /mongodb/mongod-b2-config.yml
touch /mongodb/mongod-c2-config.yml
touch /mongodb/mongod-configserver2.yml

# 登陆到192.168.3.75
mkdir -p /mongodb/a3
mkdir -p /home/log/mongodb/a3
mkdir -p /mongodb/b3
mkdir -p /home/log/mongodb/b3
mkdir -p /mongodb/c3
mkdir -p /home/log/mongodb/c3
 
mkdir -p /mongodb/configserver3
mkdir -p /home/log/mongodb/configserver3
 
touch /mongodb/mongod-a3-config.yml
touch /mongodb/mongod-b3-config.yml
touch /mongodb/mongod-c3-config.yml
touch /mongodb/mongod-configserver3.yml

# 登陆到192.168.3.73
# 生产和copy秘钥用户实例内部认证
 
openssl rand -base64 755 > /mongodb/keyfile
chmod 400 /mongodb/keyfile
 
scp /mongodb/keyfile root@192.168.3.74:/mongodb/
scp /mongodb/keyfile root@192.168.3.75:/mongodb/

列举mongod-a1-config.yml文件。

# yml
# mongod config
# 日志位置
systemLog:
  destination: file
  logAppend: true
  path: /home/log/mongodb/a1/mongodb.log
# Where and how to store data.
# db存储位置
storage:
  dbPath: /mongodb/a1
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# how the process runs
# fork : fork and run in background  后台运行
# pidFilePath:location of pidfile 
processManagement:
  fork: true
  pidFilePath: /var/run/mongod-a1.pid
 
# network interfaces
# Listen to local interface only, comment to listen on all interfaces.
net:
  port: 28111
  bindIp: 0.0.0.0
 
#security:  enabled  disabled
#security:
#  keyFile: /mongodb/keyfile
#  clusterAuthMode: keyFile
 
#operationProfiling:
operationProfiling:
   slowOpThresholdMs: 1000
   mode: slowOp
 
#replication:
 
replication:
  replSetName: fang-s-a
 
#sharding:
 
sharding:
  clusterRole: shardsvr
 
## Enterprise-Only Options
 
#auditLog:
 
#snmp:

刚才touch的文件按照名称修改配置,好比mongod-b1-config.yml须要修改的内容:a1所有替换问b1, fang-s-a替换为fang-s-b,端口按照规划的28111改成28112

configserver稍微有点不同的是clusterRole,注意修改,一个为shardsvr,一个为configsvr,其余同理,不一样服务器修改数据和配置。按照前面建立的文件名称,目录名称修改。也给出一个配置服务的例子

# yml
# mongod config
 
systemLog:
  destination: file
  logAppend: true
  path: /home/log/mongodb/configserver1/mongodb.log
 
 
# Where and how to store data.
storage:
  dbPath: /mongodb/configserver1
  journal:
    enabled: true
#  engine:
#  mmapv1:
#  wiredTiger:

# how the process runs
# fork : fork and run in background
# pidFilePath:location of pidfile
processManagement:
  fork: true
  pidFilePath: /var/run/mongod-configserver1.pid
 
# network interfaces
# Listen to local interface only, comment to listen on all interfaces.
net:
  port: 28200
  bindIp: 0.0.0.0
 
 
#security:  enabled  disabled
#security:
#  keyFile: /mongodb/keyfile
#  clusterAuthMode: keyFile
 
#operationProfiling:
operationProfiling:
   slowOpThresholdMs: 1000
   mode: slowOp
 
#replication:
 
replication:
  replSetName: fang-cs
 
#sharding:
 
sharding:
  clusterRole: configsvr
 
## Enterprise-Only Options
 
#auditLog:
 
#snmp:


启动全部实例:

#  登陆到192.168.3.73
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongod -f /mongodb/mongod-a1-config.yml
./mongod -f /mongodb/mongod-b1-config.yml
./mongod -f /mongodb/mongod-c1-config.yml
./mongod -f /mongodb/mongod-configserver1.yml

# 其余两台相似,启动其余8个实例
#  登陆到192.168.3.74
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongod -f /mongodb/mongod-a2-config.yml
./mongod -f /mongodb/mongod-b2-config.yml
./mongod -f /mongodb/mongod-c2-config.yml
./mongod -f /mongodb/mongod-configserver2.yml
 
#  登陆到192.168.3.75
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongod -f /mongodb/mongod-a3-config.yml
./mongod -f /mongodb/mongod-b3-config.yml
./mongod -f /mongodb/mongod-c3-config.yml
./mongod -f /mongodb/mongod-configserver3.yml

建立replicat set

# 登陆到192.168.3.73
 
./mongo 127.0.0.1:28111/admin
 
> use admin
switched to db admin
 
# 初始化fang-s-a的副本集
> rs.initiate()
{
        "info2" : "no configuration specified. Using a default configuration for the set",
        "me" : "73.dooioo.org:28111",
        "ok" : 1
}
 
# 添加到副本集
fang-s-a:OTHER> rs.add("74.dooioo.org:28111")
{ "ok" : 1 }
fang-s-a:PRIMARY> rs.add("75.dooioo.org:28111")
{ "ok" : 1 }
 
# 看下副本集配置状况
fang-s-a:PRIMARY> rs.conf()
{
        "_id" : "fang-s-a",
        "version" : 3,
        "protocolVersion" : NumberLong(1),
        "members" : [
                {
                        "_id" : 0,
                        "host" : "73.dooioo.org:28111",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {
 
                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 1,
                        "host" : "74.dooioo.org:28111",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {
 
                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                },
                {
                        "_id" : 2,
                        "host" : "75.dooioo.org:28111",
                        "arbiterOnly" : false,
                        "buildIndexes" : true,
                        "hidden" : false,
                        "priority" : 1,
                        "tags" : {
 
                        },
                        "slaveDelay" : NumberLong(0),
                        "votes" : 1
                }
        ],
        "settings" : {
                "chainingAllowed" : true,
                "heartbeatIntervalMillis" : 2000,
                "heartbeatTimeoutSecs" : 10,
                "electionTimeoutMillis" : 10000,
                "getLastErrorModes" : {
 
                },
                "getLastErrorDefaults" : {
                        "w" : 1,
                        "wtimeout" : 0
                },
                "replicaSetId" : ObjectId("57c00e2b9f6b9f6453c488c3")
        }
}

能够自行插入记录看看同步效果:

# 登陆到192.168.3.74  初始化fang-s-b 添加副本集
./mongo 127.0.0.1:28112/admin
rs.initiate()
rs.add("73.dooioo.org:28112")
rs.add("75.dooioo.org:28112")
# 登陆到192.168.3.75  初始化fang-s-c 添加副本集
./mongo 127.0.0.1:28113/admin
rs.initiate()
rs.add("73.dooioo.org:28113")
rs.add("74.dooioo.org:28113")
 
# 登陆到192.168.3.74  初始化fang-cs添加副本集
./mongo 127.0.0.1:28200/admin
rs.initiate()
rs.add("74.dooioo.org:28200")
rs.add("75.dooioo.org:28200")

添加分片集群:

# 登陆到192.168.3.73
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongos --port 28300 --configdb fang-cs/73.dooioo.org:28200,74.dooioo.org:28200,75.dooioo.org:28200 --fork --logpath /home/log/mongodb/mongos.log --bind_ip 0.0.0.0

经过mongos来登陆:

# 登陆到192.168.3.73
cd /root/mongodb-linux-x86_64-rhel62-3.2.9/bin
./mongo 127.0.0.1:28300/admin

mongos> use admin
switched to db admin
mongos> sh.addShard("fang-s-a/73.dooioo.org:28111,74.dooioo.org:28111,75.dooioo.org:28111")
{ "shardAdded" : "fang-s-a", "ok" : 1 }
mongos> sh.addShard("fang-s-b/73.dooioo.org:28112,74.dooioo.org:28112,75.dooioo.org:28112")
{ "shardAdded" : "fang-s-b", "ok" : 1 }
mongos> sh.addShard("fang-s-c/73.dooioo.org:28113,74.dooioo.org:28113,75.dooioo.org:28113")
{ "shardAdded" : "fang-s-c", "ok" : 1 }
mongos>

没有安全认证的集群就搭建好了,下面是关于安全认证的。

创建安全

秘钥文件keyfile

   生成秘钥文件

openssl rand -base64 755 > /mongodb/keyfile
chmod 400 /mongodb/keyfile
scp keyfile root@192.168.3.74:/mongodb/
scp keyfile root@192.168.3.75:/mongodb/

建立用户,登陆到一个mongos实例,为集群建立root用户

db.createUser({ user: "root******",pwd: "**************",roles: [ "root", "userAdminAnyDatabase", "userAdmin", "dbOwner" ]})

全部实例所有中止,使用

./mongod -f /mongodb/mongod-a1-config.yml --shutdown

mongod实例启动添加参数 --keyFile /mongodb/keyfile --auth

启动时能够不使用 --auth参数,由于使用了 --keyFile就必须验证,也就是隐含了 --auth。可是--auth并不隐含 --keyFile。

测试,iostat,观察使用状况

例如,如下命令会每隔一秒展现额外的统计数据和每次展现报表的时间(以MB/s为流量单位):

iostat -xmt 1

Key fields from iostat:

%util: 这对快速查看来讲是最有用的字段,它指明了设备/驱动器使用时间的百分比。
avgrq-sz:平均请求大小。该值较小的数字反映了更多的随机IO操做。

核武MongoDB Ops Manager


下面介绍下核武MongoDB Ops Manager。

安装:

机器同上(CentOS release 6.6)。官方推荐要求15 GB memory and 50 GB disk space。df -h校验。测试用,少一些不要紧。这里测试机器30G硬盘空间,4G内存。须要有root帐号。首先安装一个mongod实例,做为ops的db。到官网上下载Ops Manager包,我这里下载的是mongodb-mms-2.0.5.358-1.x86_64.rpm。

执行

sudo rpm -ivh mongodb-mms-2.0.5.358-1.x86_64.rpm
 
sudo service mongodb-mms start

配置文件位置/opt/mongodb/mms/conf/conf-mms.properties
默认访问8080端口,https://192.168.3.81:8080/.

帐号配置

略,好比修改时区为北京时间。

新的部署

登陆,能够选择部署新的集群和,管理手动建立的集群

wKiom1nY0kSw1srvAAFvQdBvXKU346.png选择Build New Deployment Where would you like to deploy MongoDB?
选择 Deployment in other remote. What type of MongoDB deployment would you like to build?
选择 Sharded Cluster Provide details fZ喎"/kf/ware/vc/" target="_blank" class="keylink">vciB5b3VyIHNoYXJkZWQgY2x1c3RlciC55ruuxOO1xLyvyLrF5NbDPGJyIC8+DQpDbHVzdGVyIE5hbWUgOiBtZGItdGVzdC1jbHVzdGVyIFNoYXJkIENvdW50IDogNCBOb2RlcyBQZXIgU2hhcmQgOiAzIFNoYXJkIE5hbWUgUHJlZml4IDogbWRiLXRlc3QgRGF0YSBEaXJlY3RvcnkgUHJlZml4IDogL2RhdGEgSW5zdGFsbCBhbiBBdXRvbWF0aW9uIEFnZW50IG9uIGVhY2ggc2VydmVyLiDU2sO/uPa3/s7xxvewstew19S2r7T6wO23/s7xoaMgxKzIz9Do0qoxMrj2t/7O8cb3o6zS8s6qIDQqIDOjrNXiwO+3/s7xxvfJ2aOs0aHU8TTMqLf+zvHG96GjPGJyIC8+DQrRodTxz8LU2LCy17DF5NbDtPrA7bf+zvHG96O6ILv5sb7Kx9K7sr3Su7K9ytaw0crWwcujrA0KPHA+z8LU2LT6wO2w/DwvcD4NCjxwcmUgY2xhc3M9"brush:sql;"> curl -OL https://192.168.3.81:8080/download/agent/automation/mongodb-mms-automation-agent-manager-2.5.19.1732-1.x86_64.rpm

安装代理包

sudo rpm -U mongodb-mms-automation-agent-manager-2.5.19.1732-1.x86_64.rpm

打开配置文件,编辑配置,数据库指定了目录的,必须建立目录。

sudo vi /etc/mongodb-mms/automation-agent.config


mmsGroupId=57be67ffe4b09e1dfa498ee7
mmsApiKey=e5b83213955c886d0ef8ce3324cf8f30
mmsBaseUrl=

sudo mkdir -p /data
sudo chown mongod:mongod /data
 
sudo service mongodb-mms-automation-agent start

验证经过后,下一步。初始了默认的一些实例:

你也能够移动。先按默认的下一步。

而后提示: We are deploying your changes. This might take a few minutes…

相关文章
相关标签/搜索