分布式之redis复习精讲

本文围绕以下几点进行阐述 - 1、为什么使用redis - 2、使用redis有什么缺点 - 3、单线程的redis为什么这么快 - 4、redis的数据类型,以及每种数据类型的使用场景 - 5、redis的过期策略以及内存淘汰机制 - 6、redis和数据库双写一致性问题 - 7、如何应对缓存穿透和缓存雪崩问题 - 8、如何解决redis的并发竞争问题 **1、为什么使用redis** 分析:博主觉得在项目中使用redis,主要是从两个角度去考虑:性能和并发。当然,redis还具备可以做分布式锁等其他功能,但是如果只是为了分布式锁这些其他功能,完全还有其他中间件(如zookpeer等)代替,并不是非要使用redis。因此,这个问题主要从性能和并发两个角度去答。 回答:如下所示,分为两点 (一)性能 如下图所示,我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。 ![Redis性能](http://xywen.com/static/uploads/155291165524.png "在这里输入图片标题") 题外话:忽然想聊一下这个迅速响应的标准。其实根据交互效果的不同,这个响应时间没有固定标准。不过曾经有人这么告诉我:"在理想状态下,我们的页面跳转需要在瞬间解决,对于页内操作则需要在刹那间解决。另外,超过一弹指的耗时操作要有进度提示,并且可以随时中止或取消,这样才能给用户最好的体验。" 那么瞬间、刹那、一弹指具体是多少时间呢? 根据《摩诃僧祗律》记载 一刹那者为一念,二十念为一瞬,二十瞬为一弹指,二十弹指为一罗预,二十罗预为一须臾,一日一夜有三十须臾。 那么,经过周密的计算,一瞬间为0.36 秒,一刹那有 0.018 秒.一弹指长达 7.2 秒。 (二)并发 如下图所示,在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。 ![并发](http://xywen.com/static/uploads/155291165970.png "在这里输入图片标题") **2、使用redis有什么缺点** 分析:大家用redis这么久,这个问题是必须要了解的,基本上使用redis都会碰到一些问题,常见的也就几个。 回答:主要是四个问题 - (一)缓存和数据库双写一致性问题 - (二)缓存雪崩问题 - (三)缓存击穿问题 - (四)缓存的并发竞争问题 这四个问题,我个人是觉得在项目中,比较常遇见的,具体解决方案,后文给出。 **3、单线程的redis为什么这么快** 分析:这个问题其实是对redis内部机制的一个考察。其实根据博主的面试经验,很多人其实都不知道redis是单线程工作模型。所以,这个问题还是应该要复习一下的。 回答:主要是以下三点 (一)纯内存操作 (二)单线程操作,避免了频繁的上下文切换 (三)采用了非阻塞I/O多路复用机制 题外话:我们现在要仔细的说一说I/O多路复用机制,因为这个说法实在是太通俗了,通俗到一般人都不懂是什么意思。博主打一个比方:小曲在S城开了一家快递店,负责同城快送服务。小曲因为资金限制,雇佣了一批快递员,然后小曲发现资金不够了,只够买一辆车送快递。 经营方式一 客户每送来一份快递,小曲就让一个快递员盯着,然后快递员开车去送快递。慢慢的小曲就发现了这种经营方式存在下述问题 几十个快递员基本上时间都花在了抢车上了,大部分快递员都处在闲置状态,谁抢到了车,谁就能去送快递 随着快递的增多,快递员也越来越多,小曲发现快递店里越来越挤,没办法雇佣新的快递员了 快递员之间的协调很花时间 综合上述缺点,小曲痛定思痛,提出了下面的经营方式 经营方式二 小曲只雇佣一个快递员。然后呢,客户送来的快递,小曲按送达地点标注好,然后依次放在一个地方。最后,那个快递员依次的去取快递,一次拿一个,然后开着车去送快递,送好了就回来拿下一个快递。 对比 上述两种经营方式对比,是不是明显觉得第二种,效率更高,更好呢。在上述比喻中: 每个快递员------------------>每个线程 每个快递-------------------->每个socket(I/O流) 快递的送达地点-------------->socket的不同状态 客户送快递请求-------------->来自客户端的请求 小曲的经营方式-------------->服务端运行的代码 一辆车---------------------->CPU的核数 于是我们有如下结论 - 1、经营方式一就是传统的并发模型,每个I/O流(快递)都有一个新的线程(快递员)管理。 - 2、经营方式二就是I/O多路复用。只有单个线程(一个快递员),通过跟踪每个I/O流的状态(每个快递的送达地点),来管理多个I/O流。 下面类比到真实的redis线程模型,如图所示 ![redis线程模型](http://xywen.com/static/uploads/155291166572.png "在这里输入图片标题") 参照上图,简单来说,就是。我们的redis-client在操作的时候,会产生具有不同事件类型的socket。在服务端,有一段I/0多路复用程序,将其置入队列之中。然后,文件事件分派器,依次去队列中取,转发到不同的事件处理器中。 需要说明的是,这个I/O多路复用机制,redis还提供了select、epoll、evport、kqueue等多路复用函数库,大家可以自行去了解。 **4、redis的数据类型,以及每种数据类型的使用场景** 分析:是不是觉得这个问题很基础,其实我也这么觉得。然而根据面试经验发现,至少百分八十的人答不上这个问题。建议,在项目中用到后,再类比记忆,体会更深,不要硬记。基本上,一个合格的程序员,五种类型都会用到。 回答:一共五种 - (一)String 这个其实没啥好说的,最常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。 - (二)hash 这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果。 - (三)list 使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。 - (四)set 因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。 另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。 - (五)sorted set sorted set多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作。另外,参照另一篇《分布式之延时任务方案解析》,该文指出了sorted set可以用来做延时任务。最后一个应用就是可以做范围查找。 **5、redis的过期策略以及内存淘汰机制** 分析:这个问题其实相当重要,到底redis有没用到家,这个问题就可以看出来。比如你redis只能存5G数据,可是你写了10G,那会删5G的数据。怎么删的,这个问题思考过么?还有,你的数据已经设置了过期时间,但是时间到了,内存占用率还是比较高,有思考过原因么? 回答:redis采用的是定期删除+惰性删除策略。 为什么不用定时删除策略? 定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略. 定期删除+惰性删除是如何工作的呢? 定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。 于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。 采用定期删除+惰性删除就没其他问题了么? 不是的,如果定期删除没删除key。然后你也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。 在redis.conf中有一行配置 ``` maxmemory-policy volatile-lru ``` 该配置就是配内存淘汰策略的(什么,你没配过?好好反省一下自己) - 1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。 - 2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。推荐使用,目前项目在用这种。 - 3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。应该也没人用吧,你不删最少使用Key,去随机删。 - 4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐 - 5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。依然不推荐 - 6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐 ps:如果没有设置 expire 的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。 **6、redis和数据库双写一致性问题** 分析:一致性问题是分布式常见问题,还可以再分为最终一致性和强一致性。数据库和缓存双写,就必然会存在不一致的问题。答这个问题,先明白一个前提。就是如果对数据有强一致性要求,不能放缓存。我们所做的一切,只能保证最终一致性。另外,我们所做的方案其实从根本上来说,只能说降低不一致发生的概率,无法完全避免。因此,有强一致性要求的数据,不能放缓存。 回答:《分布式之数据库和缓存双写一致性方案解析》给出了详细的分析,在这里简单的说一说。首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。 **7、如何应对缓存穿透和缓存雪崩问题** 分析:这两个问题,说句实在话,一般中小型传统软件企业,很难碰到这个问题。如果有大并发的项目,流量有几百万左右。这两个问题一定要深刻考虑。 回答:如下所示 缓存穿透,即黑客故意去请求缓存中不存在的数据,导致所有的请求都怼到数据库上,从而数据库连接异常。 解决方案: - (一)利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试 - (二)采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。 - (三)提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。 缓存雪崩,即缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常。 解决方案: - (一)给缓存的失效时间,加上一个随机值,避免集体失效。 - (二)使用互斥锁,但是该方案吞吐量明显下降了。 - (三)双缓存。我们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。自己做缓存预热操作。然后细分以下几个小点 - I 从缓存A读数据库,有则直接返回 - II A没有数据,直接从B读数据,直接返回,并且异步启动一个更新线程。 - III 更新线程同时更新缓存A和缓存B。 **8、如何解决redis的并发竞争key问题** 分析:这个问题大致就是,同时有多个子系统去set一个key。这个时候要注意什么呢?大家思考过么。需要说明一下,博主提前百度了一下,发现答案基本都是推荐用redis事务机制。博主不推荐使用redis的事务机制。因为我们的生产环境,基本都是redis集群环境,做了数据分片操作。你一个事务中有涉及到多个key操作的时候,这多个key不一定都存储在同一个redis-server上。因此,redis的事务机制,十分鸡肋。 回答:如下所示 - (1)如果对这个key操作,不要求顺序 这种情况下,准备一个分布式锁,大家去抢锁,抢到锁就做set操作即可,比较简单。 - (2)如果对这个key操作,要求顺序 假设有一个key1,系统A需要将key1设置为valueA,系统B需要将key1设置为valueB,系统C需要将key1设置为valueC. 期望按照key1的value值按照 valueA-->valueB-->valueC的顺序变化。这种时候我们在数据写入数据库的时候,需要保存一个时间戳。假设时间戳如下 - 系统A key 1 {valueA 3:00} - 系统B key 1 {valueB 3:05} - 系统C key 1 {valueC 3:10} 那么,假设这会系统B先抢到锁,将key1设置为{valueB 3:05}。接下来系统A抢到锁,发现自己的valueA的时间戳早于缓存中的时间戳,那就不做set操作了。以此类推。 其他方法,比如利用队列,将set方法变成串行访问也可以。总之,灵活变通。 转自:https://www.cnblogs.com/rjzheng/p/9096228.html

Posted by xywen on 2019-03-18 20:20:45

   Redis , Redis数据类型 , 分布式

Python中六大数据类型

**数字(number)** 单斜扛(/)除法的结果一定是float浮点类型,注意:在不同的机器上结果(精度)有可能不同哦,比如在32位和在64位的机器上结果可能就不一样了. 双斜扛(//)除法的特点有点类似“取商”,也就是说如果不能整除,结果只会保留小数点前面的数值,小数点后面的数值会全部舍弃掉。还有,如果除数和被除数中都是int整数类型,那结果也一定是int整数类型;如果除数和被除数中有一个是float浮点类型,结果也一定是浮点类型;所以,双斜扛(//)除法的结果并不一定是整数哦! **字符串(string)(定义常量一般用大写字母)** 1.使用单引号或者双引号( ' 或 " )来创建字符串,且Python中字符串不能改变 2.字符串使用单/双引号是没有任何区别的,也可以相互嵌套使用 3.三引号(''' 或者 """)除了用以多行注释,还常用来定义多行多语句文档字符串,可以包含换行符、制表符以及其他特殊字符 4.用反斜杠对特殊字符转义, 反斜扛出现行尾,表示续行符; (回车), (换行), '(单引号), "(单引号), \(转义)等等 如果不想让字符串中的特殊字符进行转义,可以在字符串前加r或R 5.在Python3.x中所有的字符串都是Unicode字符串,且源码文件默认是UTF-8编码方式,UTF-8是unicode的一种实现方式 **列表(list)** Python总共有6个内置的序列,即列表、元组、字符串、Unicode字符串、buffer对象和 xrange 对象。 序列的操作包括:索引、长度、切片、遍历、组合(序列相加)、检查成员、重复(乘法)、最小值和最大值。 使用方括号[ ]来创建列表,元素item间用逗号(,)隔开 data = [1,2,4,5] 列表推导式: [表达式 for 变量 in 可迭代对象] 或 [表达式 for 变量 in 可迭代对象 if 条件] **元组(tuple)** 元组的定义,它是用小括号( )来创建的,元素item间用逗号(,)隔开 data = (1,2,3,4,6) 注意:当元组tuple内只有一个元素时,元素后面必须要加上一个逗号(,);否则Python解释器会把小括号当作运算符来计算,其结果就是一个整数5;为了消除这种歧义,Python要求在定义只有一个元素的元组时,元素的后面必须加上一个逗号(,);这点和列表list是不相同的。 **字典(dict)** 字典dict定义,它里面的元素是“健值对”形式,包裹在花括号{ }里面,用冒号(:)将键key与值value隔开;“键值对”之间用逗号(,)分开,也就是元素之间用逗号(,)分开,这点和list,tuple是一样的。 data= {"key1": "value1", "key2": "value2"} 注意:键key在字典里是唯一的,不允许同一个键Key出现两次;类型必须是不可变的,如数字,字符串,元组等;键key对应的值value可以是任何数据类型。 **集合(set)** 注意:创建一个空集合必须用set()而不是花括号{ },因为花括号{ }是用来创建一个空字典的, set = {value1,value2,...} 或 set = set(value) set(iterable) :参数是一个可迭代对象,比如:字符串,列表,元组,字典等 集合set可以创建一个无序不重复元素集,用来确认逻辑关系,删除重复数据,还可以计算交集、差集、并集等;

Posted by xywen on 2019-02-26 14:54:39

   数字(number) , 字符串(string) , 列表(list) , 元组(tuple) , 字典(dict) , 集合(set)

CentOS7 安装polipo

下载: git clone https://github.com/jech/polipo.git cd polipo (可选)使用发布的版本 git checkout polipo-1.1.1 安装: make all su -c 'make install' 建立配置文件: mkdir /opt/polipo nano /opt/polipo/config 复制http://www.pps.univ-paris-diderot.fr/~jch/software/polipo/config.sample 内容并编辑 建立polipo账户 useradd polipo -r -s /usr/sbin/nologin 新建启动脚本: nano /etc/systemd/system/polipo.service 内容为 [Unit] Description=polipo web proxy After=network.target [Service] Type=simple WorkingDirectory=/tmp User=polipo Group=polipo ExecStart=/usr/bin/polipo -c /opt/polipo/config Restart=always SyslogIdentifier=Polipo [Install] WantedBy=multi-user.target 打开防火墙: firewall-cmd --permanent --add-port=8123/tcp firewall-cmd --reload 尝试启动服务: systemctl start polipo 查看是否被selinux阻挡: sudo cat /var/log/audit/audit.log | grep polipo | grep denied 配置selinux rule: sudo cat /var/log/audit/audit.log | grep polipo | grep denied | audit2allow -M mypolipo sudo semodule -i mypolipo.pp 重复以上操作直至selinux不再阻挡 自动启动服务: systemctl enable polipo sslocal: pip install shadowsocks 启动1080服务: sslocal -s 139.100.144.030 -p 12345 -k adfkjIJad -l 1080 -t 600 -m aes-256-cfb & 重启polipo: systemctl restart polipo 修改:~/.base_profile function start_proxy { export http_proxy='http://127.0.0.1:8123' export https_proxy='http://127.0.0.1:8123' } source ~/.base_profile

Posted by xywen on 2019-02-25 13:07:44

   安装polipo , CentOS

CentOS安装 RabbitMQ及运行环境Erlang

安装运行环境(Erlang): wget http://packages.erlang-solutions.com/erlang-solutions-1.0-1.noarch.rpm rpm -Uvh erlang-solutions-1.0-1.noarch.rpm rpm --import 安装erlang: yum install erlang 安装RabbitMQ: wget http://www.rabbitmq.com/releases/rabbitmq-server/v3.5.1/rabbitmq-server-3.5.1-1.noarch.rpm rpm --import http://www.rabbitmq.com/rabbitmq-signing-key-public.asc yum install rabbitmq-server-3.5.1-1.noarch.rpm 常用操作: 开机启动: chkconfig rabbitmq-server on 启动:/sbin/service rabbitmq-server start Web管理界面插件: rabbitmq-plugins enable rabbitmq_management 添加用户:rabbitmqctl add_user admin 123456 添加权限:rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*" 修改用户角色rabbitmqctl set_user_tags admin administrator rabbitmqctl -q status //打印了一些rabbitmq服务状态信息,包括内存,硬盘,和使用erlong的版本信息 rabbitmqctl list_queues //查看所有队列消息

Posted by xywen on 2019-02-25 13:00:32

   Erlang , RabbitMQ

Elasticsearch 和 Elasticsearch Head 、IK、mapper-murmur3安装

**安装Java运行环境**:yum install java-1.8.0-openjdk 下载官方版:wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6.13.zip ik: ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v5.6.13/elasticsearch-analysis-ik-5.6.13.zip(跟ES版本对应) mapper-murmur3: sudo bin/elasticsearch-plugin install mapper-murmur3 head: 1. git clone git://github.com/mobz/elasticsearch-head.git 2. cd elasticsearch-head 3. sudo yum install nodejs 4. npm install -g 5. npm run start 6. cd elasticsearch-head/node_modules/grunt/node_modules/grunt-cli/bin ./grunt server groupadd elsearch useradd elsearch -g elsearch -p elasticsearch passwd elsearch # 设置密码 在/etc/systemd/system目录下创建elasticsearch.service文件 [Unit] Description=elasticsearch [Service] User=elasticsearch LimitNOFILE=100000 LimitNPROC=100000 ExecStart=/usr/local/elasticsearch/bin/elasticsearch [Install] WantedBy=multi-user.target 设置开机自启 systemctl enable elasticsearch

Posted by xywen on 2019-02-25 12:58:00

   Elasticsearch Head , Elasticsearch IK , Elasticsearch mapper-murmur3

MongoDB安装和增加密码验证

**针对Mac OS 安装:** 安装: brew install mongodb 启动: brew services start mongodb 重启: brew services restart mongodb 停止: brew services stop mongodb 配置文件: /usr/local/etc/mongod.conf **针对CentOS** #### 一、安装 1. 新建/etc/yum.repos.d/mongodb-org-4.0.repo并把以下内容写入新建的文件 [mongodb-org-4.0] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc 2.执行:sudo yum install -y mongodb-org 3.等待执行完成之后启动sudo service mongod start 停止:sudo service mongod stop 重启:sudo service mongod restart #### 二、配置(CentOS和MacOS通用,只是默认配置文件目录不一样) 1.MongoDB默认配置文件是在/etc/mongodb.conf(CentOS) dbpath 数据库路径(数据文件) #默认数据库文件路径: /var/lib/mongo logpath 日志文件路径 #默认日志文件path: /var/log/mongodb/mongod.log master 指定为主机器 slave 指定为从机器 source 指定主机器的IP地址 pologSize 指定日志文件大小不超过64M.因为resync是非常操作量大且耗时,最好通过设置一个足够大的 oplogSize来避免resync(默认的 oplog大小是空闲磁盘大小的5%)。 logappend 日志文件末尾添加,即使用追加的方式写日志 journal 启用日志 port 启用端口号 fork 在后台运行 only 指定只复制哪一个数据库 slavedelay 指从复制检测的时间间隔 auth 是否需要验证权限登录(用户名和密码) syncdelay 数据写入硬盘的时间(秒),0是不等待,直接写入 notablescan 不允许表扫描 maxConns 最大的并发连接数,默认2000 pidfilepath 指定进程文件,不指定则不产生进程文件 bind_ip 绑定IP,绑定后只能绑定的IP访问服务 2.修改配置文件(增加密码) a.运行mongo b. use admin 进入admin数据库 c. 执行db.createUser({ user: "root", pwd: "newpassword", roles: [{ role: "root", db: "admin" }] }) d. 退出 e. vim /etc/mongodb.conf 找到配置项security 并修改成security:authorization: enabled 修改CentOS系统启动时自动启动项 vim /etc/systemd/system/multi-user.target.wants/mongod.service 找到:ExecStart=/usr/bin/mongod $OPTIONS 修改成ExecStart=/usr/bin/mongod --auth $OPTIONS 最后执行sudo systemctl daemon-reload加载启动项 f. 重启MongoDB sudo service mongod restart **常用命令:** 备份数据库:mongodump -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -o 文件存在路径 导出所有数据库:mongodump -h 127.0.0.1 -o /home/zhangy/mongodb/ 导出指定数据库:mongodump -h 192.168.1.108 -d tank -o /home/zhangy/mongodb/ 还原数据库: mongorestore -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 --drop 文件存在路径 mongodb导出表:mongoexport -d tank -c users -o /home/zhangy/mongodb/tank/users.dat mongodb导入表:mongoimport -h IP --port 端口 -u 用户名 -p 密码 -d 数据库 -c 表名 --upsert --drop 文件名 部分字段的表数据导入: mongoimport -d tank -c users --upsertFields uid,name,sex tank/users.dat 导出表中部分字段:mongoexport -d tank -c users --csv -f uid,name,sex -o tank/users.csv 创建索引的命令: > db.test.ensureIndex({"username":1}) 可以通过下面的名称查看索引是否已经成功建立: > db.test.getIndexes() 删除索引的命令是: > db.test.dropIndex({"username":1}) explain会返回查询使用的索引情况,耗时和扫描文档数的统计信息 db.test.find().explain() 唯一索引 db.test.ensureIndex({"userid":1},{"unique":true}) 1、show dbs 显示当前数据库服务器上的数据库 2、use pagedb 切换到指定数据库pagedb的上下文,可以在此上下文中管理pagedb数据库以及其中的集合等 3、show collections 显示数据库中所有的集合(collection) 4、db.serverStatus() 查看数据库服务器的状态。 5、查询指定数据库统计信息 use fragment db.stats() 6、查询指定数据库包含的集合名称列表 db.getCollectionNames() 删除数据库 直接使用db.dropDatabase()即可删除数据库。 创建集合 可以使用命令db.createCollection(name, { size : ..., capped : ..., max : ... } )创建集合 删除集合 可以执行db.mycoll.drop()。 插入更新记录 直接使用集合的save方法 查询一条记录 使用findOne()函数,参数为查询条件,可选,系统会随机查询获取到满足条件的一条记录(如果存在查询结果数量大于等于1) 查询多条记录 使用find()函数,参数指定查询条件,不指定条件则查询全部记录。 删除记录 使用集合的remove()方法,参数指定为查询条件 创建索引 可以使用集合的ensureIndex(keypattern[,options])方法ensureIndex方法参数中,数字1表示升序,-1表示降序。使用db.system.indexes.find()可以查询全部索引。 查询索引 通过集合的getIndexes()方法实现查询 删除索引 给出了两个方法: db.mycoll.dropIndex(name) db.mycoll.dropIndexes() 第一个通过指定索引名称,第二个删除指定集合的全部索引。 索引重建 可以通过集合的reIndex()方法进行索引的重建 统计集合记录数 use fragment db.baseSe.count() 统计结果 查询并统计结果记录数 use fragment db.baseSe.find().count() find()可以提供查询参数,然后查询并统计结果。统计了查询数据库fragment的baseSe结果记录集合中记录数。 查询指定数据库的集合当前可用的存储空间 use fragment > db.baseSe.storageSize() 142564096 查询指定数据库的集合分配的存储空间 > db.baseSe.totalSize() 144096000 上述查询结果中,包括为集合(数据及其索引存储)分配的存储空间。

Posted by xywen on 2019-02-24 16:35:45

   CentOS7 , MongoDB , MongoDB安装 , MongoDB密码验证

进程管理supervisor(CentOS)

**安装supervisor: pip install supervisor** #### 一、配置: **默认配置文件**: supervisor的默认配置文件是在 /etc/supervisord.conf ;[program:theprogramname] 这个就是咱们要管理的子进程了,":"后面的是名字,最好别乱写和实 际进程有点关联最好。这样的program我们可以设置一个或多个,一个 program就是要被管理的一个进程 ;command=/bin/cat 这个就是我们的要启动进程的命令路径了,可以带参数例 子:/home/test.py -a 'hehe'有一点需要注意的是,我们的 command只能是那种在终端运行的进程,不能是守护进程。这个想想也 知道了,比如说command=service httpd start。httpd这个进程 被linux的service管理了,我们的supervisor再去启动这个命令这 已经不是严格意义的子进程了。这个是个必须设置的项 ;process_name=%(program_name)s 这个是进程名,如果我们下面的numprocs参数为1的话,就不用管这个 参数了,它默认值%(program_name)s也就是上面的那个program冒号 后面的名字,但是如果numprocs为多个的话,那就不能这么干了。想想 也知道,不可能每个进程都用同一个进程名吧。 ;numprocs=1 启动进程的数目。当不为1时,就是进程池的概念,注意process_name 的设置默认为1 。。非必须设置 ;directory=/tmp 进程运行前,会前切换到这个目录默认不设置。。。非必须设置 ;umask=022 进程掩码,默认none,非必须 ;priority=999 子进程启动关闭优先级,优先级低的,最先启动,关闭的时候最后关闭默 认值为999 。。非必须设置 ;autostart=true 如果是true的话,子进程将在supervisord启动后被自动启动、默认就 是true, 非必须设置 ;autorestart=unexpected 这个是设置子进程挂掉后自动重启的情况,有三个false,unexpected 和true。如果为false的时候,无论什么情况下,都不会被重新启动, 如果为unexpected,只有当进程的退出码不在下面的exitcodes里面 定义的退 出码的时候,才会被自动重启。当为true的时候,只要子进程 挂掉,将会被无条件的重启 ;startsecs=1 这个选项是子进程启动多少秒之后,此时状态如果是running,则我们 认为启动成功了默认值为1 。。非必须设置 ;startretries=3 当进程启动失败后,最大尝试启动的次数。。当超过3次后, supervisor将把此进程的状态置为FAIL默认值为3 。。非必须设置 ;exitcodes=0,2 注意和上面的的autorestart=unexpected对应。。exitcodes里面 的定义的退出码是expected的。 ;stopsignal=QUIT 进程停止信号,可以为TERM, HUP, INT, QUIT, KILL, USR1, or USR2等信号默认为TERM 。。当用设定的信号去干掉进程,退出码会被 认为是expected非必须设置 ;stopwaitsecs=10 这个是当我们向子进程发送stopsignal信号后,到系统返回信息给 supervisord,所等待的最大时间。 超过这个时间,supervisord会 向该子进程发送一个强制kill的信号。默认为10秒。。非必须设置 ;stopasgroup=false 这个东西主要用于,supervisord管理的子进程,这个子进程本身还有 子进程。那么我们如果仅仅干掉supervisord的子进程的话,子进程的 子进程有可能会变成孤儿进程。所以咱们可以设置可个选项,把整个该子 进程的整个进程组都干掉。 设置为true的话,一般killasgroup也会 被设置为true。需要注意的是,该选项发送的是stop信号默认为 false。。非必须设置。。 ;killasgroup=false 这个和上面的stopasgroup类似,不过发送的是kill信号 ;user=chrism 如果supervisord是root启动,我们在这里设置这个非root用户,可以 用来管理该program默认不设置。。。非必须设置项 ;redirect_stderr=true 如果为true,则stderr的日志会被写入stdout日志文件中默认为 false,非必须设置 ;stdout_logfile=/a/path 子进程的stdout的日志路径,可以指定路径,AUTO,none等三个选项。设 置为none的话,将没有日志产生。设置为AUTO的话,将随机找一个地方生成 日志文件,而且当supervisord重新启动的时候,以前的日志文件会被清空。 当 redirect_stderr=true的时候,sterr也会写进这个日志文件 ;stdout_logfile_maxbytes=1MB 日志文件最大大小,和[supervisord]中定义的一样。默认为50 ;stdout_logfile_backups=10 和[supervisord]定义的一样。默认10 ;stdout_capture_maxbytes=1MB 这个东西是设定capture管道的大小,当值不为0的时候,子进程可以从stdout 发送信息,而supervisor可以根据信息,发送相应的event。默认为0,为0的 时候表达关闭管道。。。非必须项 ;stdout_events_enabled=false 设置为ture的时候,当子进程由stdout向文件描述符中写日志的时候,将触发 supervisord发送PROCESS_LOG_STDOUT类型的event默认为false,非必须设置 ;stderr_logfile=/a/path 设置stderr写的日志路径,当redirect_stderr=true。这个就不用设置了, 设置了也是白搭。因为它会被写入stdout_logfile的同一个文件中默认为AUTO, 也就是随便找个地存,supervisord重启被清空。。非必须设置 ;stderr_logfile_maxbytes=1MB 这个出现好几次了,就不重复了 ;stderr_logfile_backups=10 这个也是 ;stderr_capture_maxbytes=1MB 这个一样,和stdout_capture一样。 默认为0,关闭状态 ;stderr_events_enabled=false 这个也是一样,默认为false ;environment=A="1",B="2" 这个是该子进程的环境变量,和别的子进程是不共享的 ;serverurl=AUTO **新建的配置文件**: 自己写的配置文件通常放在/etc/supervisor/conf.d/下, 然后新建test.conf文件 [program:test] #项目名 directory=/opt/bin #脚本目录 command=/usr/bin/python /opt/bin/test.py # 脚本执行命令 autostart=true #supervisor启动的时候是否随着同时启动,默认True,当程序exit的时候,这个program不会自动重启,默认unexpected autorestart=false #设置子进程挂掉后自动重启的情况,有三个选项,false,unexpected和true。如果 为false的时候,无论什么情况下,都不会被重新启动,如果为unexpected,只有当 进程的退出码不在下面的exitcodes里面定义的 startsecs=1 #这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。默认值为1 日志输出 stderr_logfile=/tmp/test_stderr.log stdout_logfile=/tmp/test_stdout.log user = test #脚本运行的用户身份 redirect_stderr = true #把 stderr 重定向到 stdout,默认 false stdout_logfile_maxbytes = 20M #stdout 日志文件大小,默认 50MB stdout_logfile_backups = 20 #stdout 日志文件备份数 [program:test] #说明同上 directory=/opt/bin command=/usr/bin/python /opt/bin/test.py autostart=true autorestart=false stderr_logfile=/tmp/test_stderr.log stdout_logfile=/tmp/test_stdout.log user = test #### 二、子进程管理(supervisorctl) - 查看所有子进程的状态: supervisorctl status test RUNNING pid 2396, uptime 0:08:41 - 关闭、开启指定的子进程: supervisorctl stop zhoujy test: stopped supervisorctl start zhoujy test: started - 关闭、开启所有的子进程: supervisorctl stop all test: stopped supervisorctl start all test: started - 重启了进程 supervisorctl restart program_name - 重新启动配置(加载配置文件并应用) supervisorctl reload

Posted by xywen on 2019-02-24 15:03:24

   CentOS7 , supervisor , supervisor配置

Python Flask Nginx Uwsgi部署

### 一、安装准备 1.Centos安装Nginx: yum install nginx 2.安装Uwsgi: - 首先安装epel扩展源: sudo yum -y install epel-release - 安装pip: sudo yum -y install python-pip - 安装uwsgi: 依赖 yum install pcre-devel python-devel gcc pip install uwsgi flask ### 二、配置 main.py文件: from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "<h1 style="color:blue">Hello There!</h1>" if __name__ == "__main__": app.run(host='0.0.0.0', port=8000) uwsgi配置: 在程序目录vim uwsgi.ini, 然后写入下面内容 [uwsgi] http = 0.0.0.0:8000 master = True processes = 4 threads = 2 module = main:app daemonize = /home/wyz/flask/server.log nginx配置: vim /etc/nginx/conf.d/test.conf server { listen 80; server_name xywen.com www.test.com; access_log /var/log/nginx/test.access.log main; error_log /var/log/nginx/tes.error.log; location / { proxy_pass http://127.0.0.1:8000; } #静态文件目录 location /static { alias /opt/test/static; autoindex off; access_log off; } } ### 三、启动程序 启动Nginx: sudo systemctl start nginx.service 检查配置文件: nginx -t 加载配置文件: nginx -s reload 启动uwsgi: uwsgi uwsgi.ini 如遇到 system max net.core.somaxconn (128) 在/etc/sysctl.conf中添加如下 net.core.somaxconn = 2048 然后在终端中执行 sysctl -p

Posted by xywen on 2019-02-22 22:34:22

   Python Flask , Nginx部署 , Uwsgi部署

Nginx安装与配置

### 一、安装Nginx其它版本 添加CentOS 7 Nginx yum资源库: sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm 开始安装:sudo yum install -y nginx 启动Nginx服务:sudo systemctl start nginx.service 网站文件存放默认目录: /usr/share/nginx/html 网站默认站点配置: /etc/nginx/conf.d/default.conf 自定义Nginx站点配置文件存放目录: /etc/nginx/conf.d/ Nginx全局配置: /etc/nginx/nginx.conf Nginx指定配置文件启动: nginx -c nginx.conf 设置CentOS 7开机启动Nginx: sudo systemctl enable nginx.service 添加Nginx用户: groupadd nginx useradd -g nginx -s /bin/false -M nginx ### 二、安装Nginx 1. Mac OS安装Nginx: brew install nginx 2. CentOS 安装: yum install nginx ### 三、Nginx配置解释 user www-data; #运行用户 worker_processes 1; #启动进程,通常设置成和cpu的数量相等 error_log /var/log/nginx/error.log; #全局错误日志及PID文件 pid /var/run/nginx.pid; events { use epoll; #工作模式及连接数上限 #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能 worker_connections 1024; #单个后台worker process进程的最大并发链接数 # multi_accept on; } #设定http服务器,利用它的反向代理功能提供负载均衡支持 http { include /etc/nginx/mime.types; #设定mime类型,类型由mime.type文件定义 default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log logs/access.log main; #设定日志格式 sendfile on; #sendfile 指令指定 nginx 是否调用 sendfile 函数(zero copy 方式)来输出文件,对于普通应用,必须设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为 off,以平衡磁盘与网络I/O处理速度,降低系统的uptime. #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #连接超时时间 tcp_nodelay on; gzip on; #开启gzip压缩 gzip_disable "MSIE [1-6]\.(?!.*SV1)"; client_header_buffer_size 1k; #设定请求缓冲 large_client_header_buffers 44k; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; #设定负载均衡的服务器列表 upstream mysvr { server 192.168.8.1:3128 weight=5; #本机上的Squid开启3128端口 server 192.168.8.2:80 weight=1; server 192.168.8.3:80 weight=6; #weigth参数表示权值,权值越高被分配到的几率越大 } server { listen 80; #侦听80端口 server_name www.xx.com; #定义使用www.xx.com访问 access_log logs/www.xx.com.access.log main; #设定本虚拟主机的访问日志 #默认请求 location / { #location允许对不同的URL使用不同的配置,即可以使用字符串也可以使用与正则表达式。 root /root; #定义服务器的默认网站根目录位置 index index.php index.html index.htm; #定义首页索引文件的名称 fastcgi_pass www.xx.com; fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name; include /etc/nginx/fastcgi_params; } error_page 500 502 503 504 /50x.html; # 如果出现指定的http错误状态码,则返回给客户端指定的url地址。 location = /50x.html { root /root; } 如果要使用负载均衡的话,可以修改配置http节点如下: #设定http服务器,利用它的反向代理功能提供负载均衡支持 http { include /etc/nginx/mime.types; #设定mime类型,类型由mime.type文件定义 default_type application/octet-stream; access_log /var/log/nginx/access.log; #设定日志格式 #省略上文有的一些配置节点 #设定负载均衡的服务器列表 upstream mysvr { #upstream指令用于设置一组可以在proxy_pass指令中使用的代理服务器,默认的代理方式为轮询。 server 192.168.8.1x:3128 weight=5;#本机上的Squid开启3128端口 server 192.168.8.2x:80 weight=1; #server指令用于指定后端服务器的名称和参数。 server 192.168.8.3x:80 weight=6; #weigth参数表示权值,权值越高被分配到的几率越大 } upstream mysvr2 { server 192.168.8.x:80 weight=1; server 192.168.8.x:80 weight=6; #weigth参数表示权值,权值越高被分配到的几率越大 } #第一个虚拟服务器 server { #在server{...}虚拟主机内可通过proxy_pass指令设置关于反向代理的upstream服务器集群。 listen 80; #侦听192.168.8.x的80端口 server_name 192.168.8.x; location ~ .*\.aspx$ { #对aspx后缀的进行负载均衡请求 root /root; #定义服务器的默认网站根目录位置 index index.php index.html index.htm; #定义首页索引文件的名称 proxy_pass http://mysvr ; #请求转向mysvr 定义的服务器列表 #以下是一些反向代理的配置可删除. proxy_redirect off; #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; #允许客户端请求的最大单文件字节数 client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数, proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时) proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时) proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时) proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小 proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置 proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2) proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传 } } }

Posted by xywen on 2019-02-22 21:28:49

   安装nginx , nginx配置 , CentOS安装Nginx , MacOS安装Nginx

安装PostgreSQL全教程

### 1.正常安装 - 1、安装包 yum install postgresql-server - 2、初始化 postgresql-setup initdb - 3、修改pg_hba.conf vim /var/lib/pgsql/data/pg_hba.conf 插入一行: host all all 192.168.1.2/32(需要连接的服务器IP) trust - 4、启动: systemctl start postgresql.service - 5、停止: systemctl enable postgresql.service - 6、修改用户密码 su - postgres 切换用户,执行后提示符会变为 '-bash-4.2$' psql -U postgres 登录数据库,执行后提示符变为 'postgres=#' ALTER USER postgres WITH PASSWORD '1e1ede7ec0b84aa79919eb99611af609' 设置postgres用户密码 \q 退出数据库 - 7、统计数据库中各表占用磁盘大小: SELECT table_schema || '.' || table_name AS table_full_name, pg_size_pretty(pg_total_relation_size('"' ||table_schema || '"."' || table_name || '"')) AS size FROM information_schema.tables ORDER BY pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC ### 二、低版本安装 1、下载9.6版本安装包: 安装rpm: yum install -y https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-centos96-9.6-3.noarch.rpm 安装客户端: yum install -y postgresql96 安装服务端:yum install -y postgresql96-server 初始化:/usr/pgsql-9.6/bin/postgresql96-setup initdb 设置开机启动: systemctl enable postgresql-9.6 运行: systemctl start postgresql-9.6 重启:systemctl restart postgresql-9.6 2、修改用户密码: 切换到postgres用户: sudo su - postgres 进入数据库: psql -U postgres 修改密码: alter user postgres with password 'postgres@newpassword' 3、修改配置: 远程访问: 修改listen_addresses = 'localhost'为listen_addresses = '*',允许所有; 主机访问: vim /var/lib/pgsql/9.6/data/pg_hba.conf (host all all 172.29.3.67/32 trust) ### 三、常用导入导出 具体某个表:pg_dump -U postgres -t mytable -f dump.sql mydatabase 导出:pg_dump -U postgres -f dump.sql mydatabase 导入:psql -d newdatabase -U postgres -f dump.sql

Posted by xywen on 2019-02-22 21:18:39

   PostgreSQL , 安装PostgreSQL

CentOS7搭建 Hadoop HBase Zookeeper集群

### 一、基础环境准备 #### 1、下载安装包(均使用当前最新的稳定版本,截止至2017年05月24日) 下载安装jdk: yum install jdk-1.8.0 yum install java-1.8.0-openjdk yum install java-1.8.0-openjdk-devel 下载 hadoop-3.0.3: wget http://www-us.apache.org/dist/hadoop/common/hadoop-3.0.3/hadoop-3.0.3.tar.gz 下载 hbase-1.4.7: wget http://www-us.apache.org/dist/hbase/1.4.7/hbase-1.4.7-bin.tar.gz 下载 zookeeper-3.4.13: wget http://mirrors.hust.edu.cn/apache/zookeeper/zookeeper-3.4.13/zookeeper-3.4.13.tar.gz #### 2、修改hosts文件(使用的三台集群主机默认IP为192.168.0.100、192.168.0.101、192.168.0.102) vim /etc/hosts 添加以下信息(master、slave1、slave2均需修改) 192.168.10.153 master 192.168.10.154 slave1 192.168.10.156 #slave2 修改hostname hostname master hostname -i 192.168.10.153 hostname slave1 hostname -i 192.168.10.154 hostname slave2 hostname -i 192.168.10.156 #### 3、配置JDK 设置jdk环境变量(master、slave1、slave2均需修改) vim /etc/environment JAVA_HOME=/usr/java/jdk1.8.0_131 JRE_HOME=/usr/java/jdk1.8.0_131/jre vim /etc/profile export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el7_5.x86_64 export CALSSPATH=$JAVA_HOME/lib/*.* export PATH=$PATH:$JAVA_HOME/bin #### 4、设置免密登陆 所有机器都需要配置如下: vim ~/.ssh/config Host master User root HostName 192.168.10.153 Port 22 Host slave1 User root HostName 192.168.10.154 Port 22 Host slave2 User root HostName 192.168.10.156 Port 22 当没有权限是:chmod 600 config slave1 ssh-keygen -t rsa cp ~/.ssh/id_rsa.pub ~/.ssh/slave1_id_rsa.pub scp ~/.ssh/slave1_id_rsa.pub master:~/.ssh/ slave2 ssh-keygen -t rsa cp ~/.ssh/id_rsa.pub ~/.ssh/slave2_id_rsa.pub scp ~/.ssh/slave2_id_rsa.pub master:~/.ssh/ master ssh-keygen -t rsa cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys cat ~/.ssh/slave1_id_rsa.pub >> ~/.ssh/authorized_keys cat ~/.ssh/slave2_id_rsa.pub >> ~/.ssh/authorized_kyes 拷贝文件至slave1及slave2 scp ~/.ssh/authorized_keys slave1:~/.ssh scp ~/.ssh/authorized_keys slave2:~/.ssh #### 5、关闭防火墙及SELINUX(master、slave1、slave2均需修改) 关闭防火墙 systemctl stop firewalld.service systemctl disable firewalld.service 关闭SELINUX vim /etc/selinux/config 注释掉 SELINUX=enforcing SELINUXTYPE=targeted 添加 SELINUX=disabled ### 二、Hadoop环境搭建 #### 1、解压缩安装包及创建基本目录 tar -zxvf hadoop-3.0.3.tar.gz -C /opt cd /opt/hadoop-2.7.3 mkdir tmp logs hdf hdf/data hdf/name #### 2、修改hadoop配置文件 修改 slaves 文件 vim /opt/hadoop-3.0.3/etc/hadoop/slaves 删除 localhost,添加 slave1 slave2 修改 core-site.xml 文件 vim /usr/hadoop-2.7.3/etc/hadoop/core-site.xml 在 configuration 节点中添加以下内容 <property> <name>fs.default.name</name> <value>hdfs://master:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>file:/usr/hadoop-2.7.3/tmp</value> </property> 修改 hdfs-site.xml 文件 vim /usr/hadoop-2.7.3/etc/hadoop/hdfs-site.xml 在 configuration 节点添加以下内容 <property> <name>dfs.datanode.data.dir</name> <value>/usr/hadoop-2.7.3/hdf/data</value> <final>true</final> </property> <property> <name>dfs.namenode.name.dir</name> <value>/usr/hadoop-2.7.3/hdf/name</value> <final>true</final> </property> 修改 mapred-site.xml 文件 cp /usr/hadoop-2.7.3/etc/hadoop/mapred-site.xml.template /usr/hadoop-2.7.3/etc/hadoop/mapred-site.xml vim /usr/hadoop-2.7.3/etc/hadoop/mapred-site.xml 在 configuration 节点添加以下内容 <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.jobhistory.address</name> <value>master:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>master:19888</value> </property> 修改 yarn-site.xml 文件 vim /usr/hadoop-2.7.3/etc/hadoop/yarn-site.xml 在configuration 节点添加以下内容 <property> <name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name> <value>org.apache.mapred.ShuffleHandler</value> </property> <property> <name>yarn.resourcemanager.address</name> <value>master:8032</value> </property> <property> <name>yarn.resourcemanager.scheduler.address</name> <value>master:8030</value> </property> <property> <name>yarn.resourcemanager.resource-tracker.address</name> <value>master:8031</value> </property> <property> <name>yarn.resourcemanager.admin.address</name> <value>master:8033</value> </property> <property> <name>yarn.resourcemanager.webapp.address</name> <value>master:8088</value> </property> #### 3、复制hadoop到slave节点 scp -r /opt/hadoop-3.0.3 slave1:/opt scp -r /opt/hadoop-3.0.3 slave2:/opt #### 4、配置 master 和 slave 的 hadoop 环境变量 vim /etc/profile 添加如下内容 export HADOOP_HOME=/opt/hadoop-3.0.3 export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH export HADOOP_LOG_DIR=/opt/hadoop-3.0.3/logs export YARN_LOG_DIR=$HADOOP_LOG_DIR 保存后执行 source /etc/profile vim ~/.bashrc 添加如下内容 export HADOOP_PREFIX=/opt/hadoop-3.0.3/ 保存后执行 source ~/.bashrc #### 5、格式化 namenode /opt/hadoop-3.0.3/sbin/hdfs namenode -format #### 6、启动 hadoop(仅在master节点执行) ssh master /opt/hadoop-3.0.3/sbin/start-all.sh ### 三、Zookeeper环境搭建 #### 1、解压缩 zookeeper 安装包到master,并建立基本目录 tar -zxvf zookeeper-3.4.13.tar.gz -C /opt mkdir /opt/zookeeper-3.4.13/data #### 2、修改master配置文件 复制配置文件模板 cp /opt/zookeeper-3.4.13/conf/zoo-sample.cfg /opt/zookeeper-3.4.13/conf/zoo.cfg 修改配置文件 vim /opt/zookeeper-3.4.13/conf/zoo.cfg 添加如下内容 dataDir=/opt/zookeeper-3.4.10/data server.1=master:2888:3888 server.2=slave1:2888:3888 server.3=slave2:2888:3888 #### 3、复制到各个子节点 scp -r /opt/zookeeper-3.4.13 slave1:/usr scp -r /opt/zookeeper-3.4.13 slave2:/usr #### 4、创建myid文件 master节点添加myid文件 ssh master touch /opt/zookeeper-3.4.13/data/myid echo 1 > /opt/zookeeper-3.4.13/data/myid slave1节点添加myid文件 ssh slave1 touch /opt/zookeeper-3.4.13/data/myid echo 2 > /opt/zookeeper-3.4.13/data/myid slave2节点添加myid文件 ssh slave2 touch /opt/zookeeper-3.4.13/data/myid echo 3 > /uoptsr/zookeeper-3.4.13/data/myid #### 5、启动zookeeper(master、slave1、slave2均需执行) 启动master ssh master cd /opt/zookeeper-3.4.13/bin ./zkServer.sh start 启动slave1 ssh slave1 cd /opt/zookeeper-3.4.13/bin ./zkServer.sh start 启动slave2 ssh slave2 cd /opt/zookeeper-3.4.13/bin ./zkServer.sh start ### 四、HBase环境搭建 #### 1、解压缩hbase安装包 tar -zxvf hbase-1.4.7.tar.gz -C /opt mkdir /opt/hbase-1.4.7/logs #### 2、修改Hbase启动时要使用的环境变量(hbase-env.sh) 打开环境变量配置文件 vim /opt/hbase-1.4.7/conf/hbase-env.sh 添加如下内容 1、设置java安装路径 export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_131 2、设置hbase的日志地址 export HBASE_LOG_DIR=${HBASE_HOME}/logs 3、设置是否使用hbase管理zookeeper(因使用zookeeper管理的方式,故此参数设置为false) export HBASE_MANAGES_ZK=false 4、设置hbase的pid文件存放路径 export HBASE_PID_DIR=/var/hadoop/pids #### 3、添加所有的region服务器到regionservers文件中 打开regionservers配置文件 vim /opt/hbase-1.4.7/conf/regionservers 删除localhost,新增如下内容 master slave1 slave2 注:hbase在启动或关闭时会依次迭代访问每一行来启动或关闭所有的region服务器进程 #### 4、修改Hbase集群的基本配置信息(hbase-site.xml),该配置将会覆盖Hbase的默认配置 打开配置文件 vim /opt/hbase-1.4.7/conf/hbase-site.xml 在configuration节点下添加如下内容 <property> <name>hbase.rootdir</name> <value>hdfs://master:9000/hbase</value> </property> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property> <property> <name>hbase.zookeeper.quorum</name> <value>master,slave1,slave2</value> </property> <property> <name>hbase.zookeeper.property.dataDir</name> <value>/usr/zookeeper-3.4.10/data</value> </property> <property> <name>hbase.master</name> <value>hdfs://master:60000</value> </property> #### 5、复制hbase到slave中 scp -r /opt/hbase-1.4.7 slave1:/opt scp -r /opt/hbase-1.4.7 slave2:/opt #### 6、启动hbase(仅在master节点上执行即可) ssh master /usr/hbase-1.4.7/bin/start-hbase.sh

Posted by xywen on 2019-02-21 23:36:14

   Hadoop , HBase , Zookeeper集群 , centos7