通知设置 新通知
所有IT技术相关英文原版书籍
学习资源 koyo 发表了文章 0 个评论 4714 次浏览 2015-11-11 14:40
新增一个hdfs的DataNode节点
大数据 空心菜 发表了文章 1 个评论 11275 次浏览 2015-11-11 01:51
场景
在hadoop中的分布式文件系统hdfs中,当存储节点磁盘使用达到预警值是,我们需要新增一个数据存储节点,来存储数据!我这里hdfs的版本是2.2.0!新增方法:
- []静态添加[/][]动态添加[/]
静态添加
静态新增的方式,就是相当于我们起初部署hdfs集群规划一样,停止NameNode,新增一个DateNode数据节点,这种方法不适用于线上提供服务的场景,具体操作如下:
1、停止NameNode节点
# cd hdfs_install_dir/sbin/
# ./hadoop-deamon.sh stop namenode
2、修改配置文件slaves文件,并修改/etc/hosts记录把新增的节点对应的ip和hostname追加到各节点
# cd hdfs_install_dir/etc/hadoop/
# echo "new_datanode_hostname" >> ./slaves
# echo "new_datanode_ip new_datanode_hostname" >> /etc/hosts
然后再利用rsync 同步配置文件和hosts文件,到各节点
3、确保Hadoop/HDFS集群的NameNode可以对新节点进行SSH免密码登录。
4、重新启动NameNode节点
5、如果你希望各数据节点磁盘使用量达到一个相对平衡的状态,就是百分比,你还需要执行hadoop balance命令,后面会具体讲到!
动态添加
动态添加,不需要停止启动NameNode节点,具体步骤如下:
1、修改所有hdfs集群机器的配置文件slaves文件,并修改/etc/hosts记录把新增的节点对应的ip和hostname追加到各节点
# cd hdfs_install_dir/etc/hadoop/
# echo "new_datanode_hostname" >> ./slaves
# echo "new_datanode_ip new_datanode_hostname" >> /etc/hosts
如果你使用ansible管理的话,hdfs集群的集群做一个叫hdfs的分组,两条命令搞定:
# ansible hdfs -m shell -a 'echo "new_datanode_hostname" >> hdfs_install_dir/etc/hadoop/slaves'
# ansible hdfs -m shell -a 'echo "new_datanode_ip new_datanode_hostname" >> /etc/hosts'
这样所有的节点slaves文件和host文件都更新了!
2、启动新增的datanode节点
# cd hdfs_install_dir/sbin
# ./hadoop-daemon.sh start datanode
3、查看是否正常加入到集群
web查看方式:http://NameNode_ip:50070/dfsnodelist.jsp?whatNodes=LIVE
命令查看方式:cd hdfs_install_dir/bin/ && ./hadoop dfsadmin -report
4、数据再平衡
添加新节点时,HDFS不会自动重新平衡。然而,HDFS提供了一个手动调用的重新平衡(reblancer)工具。这个工具将整个集群中的数据块分布调整到一个可人工配置的百分比阈值。如果在其他现有的节点上有空间存储问题,再平衡就会根据阀值,然后平衡分布数据。
执行再平衡命令,可选参数-threshold指定了磁盘容量的余量百分比,用来判定一个节点的磁盘利用率是过低还是过高。一个利用不足的数据节点其利用率低于平均利用率−阈值。过度利用的数据节点其利用率高于平均利用率+阈值。该参数设置的越小,整个集群越平衡,但会花费更多的时间进行再平衡操作。默认阈值为10%。平衡执行命令如下:
# cd hdfs_install_dir/sbin/
# ./start-balancer.sh -threshold 5
-threshold参数就是是指定平衡的阈值。
-threshold的默认是10,即每个datanode节点的实际hdfs存储使用量/集群hdfs存储量
具体解释例子如下:
datanode hdfs使用量1000G;
集群总hdfs存储量10T即10000G;
则t值为1000/10000 = 0.1 = 10%
当执行balance的-t参数小于0.1时,集群进行balance;
命令为:start-balancer.sh -threshold 10 ;
Expecting a number in the range of [1.0, 100.0]: 5%
sh $HADOOP_HOME/bin/start-balancer.sh –t 10%
这个命令中-t参数后面跟的是HDFS达到平衡状态的磁盘使用率偏差值。如果机器与机器之间磁盘使用率偏差小于10%,那么我们就认为HDFS集群已经达到了平衡的状态。
标注知识点
1、 balance命令可以在namenode或者datanode上启动,也可以随时利用stop-balance.sh脚本停止平衡!
2、balance的默认带宽是1M/s。 如果你希望修改平衡数据的带宽大小可以用./hdfs dfsadmin -setBalancerBandwidth 124288000命令指定
3、slave文件是用于重启时使用。集群的start和stop需要读取slave文件。启用datanode时只要在hdfs-site中配置了namenode位置,就可以将信息push给namenode。 这就是为什么slaves文件很重要的原因。
rsync增量传输大文件优化案例
运维 push 发表了文章 0 个评论 3702 次浏览 2015-11-09 23:21
前言
rsync用来同步数据非常的好用,特别是增量同步。但是有一种情况如果不增加特定的参数就不是很好用了。比如你要同步多个几十个G的文件,然后网络突然断开了一下,这时候你重新启动增量同步。但是发现等了好久都没有进行数据传输,倒是机器的IO一直居高不下。
原因
rsync具体的增量同步算法不太清楚。根据它的表现来看,可能在增量同步已经存在的一个文件时,会校验已传输部分数据是否已源文件一致,校验完成才继续增量同步这个文件剩下的数据。所以如果对一个大文件以这样的算法来增量同步是非常花时间并且占用IO资源的。
方法
集中花了一段时间查看了rsync的文档,发现有一个参数能快速恢复大文件的增量同步,–append。设置–append参数会在增量同步时计算文件大小并直接追加新的数据到文件,这样就省了费IO校验的过程。不过这个参数最好只在源文件和目标文件都不会更改的时候使用比较安全,比如备份的文件。
Java调用Hbase API访问接口
大数据 空心菜 发表了文章 0 个评论 4295 次浏览 2015-11-08 23:35
HBase是一个分布式的、面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系统”。就像Bigtable利用了Google文件系统(File System)所提供的分布式数据存储一样,HBase在Hadoop之上提供了类似于Bigtable的能力。HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式。HBase表一般特点:
- []大:一个表可以有上亿行,上百万列[/][]面向列:面向列(族)的存储和权限控制,列(族)独立检索[/][]稀疏:对于为空(null)的列并不占用存储空间,表可以设计非常稀疏[/]
Java 调用 Hbase 非关系型数据库,Hbase 中提供了相关的 Java API 访问接口便于使用,下面是本人综合网络总结的通过 Java 操作 HBase 进行创建、修改、删除表以及查询等。具体封装代码如下:
package yoodb.hbase;Java Hbase main函数测试类,具体代码如下:
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.HTablePool;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;
public class HBaseTest {
// 声明静态配置
static Configuration conf = null;
static final HTablePool tablePool;
static {
conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "yoodb");
tablePool = new HTablePool(conf, 15);
}
/*
* 创建表
* @tableName 表名
* @family 列族数组
*/
public static void creatTable(String tableName, String[] family)
throws Exception {
HBaseAdmin admin = new HBaseAdmin(conf);
HTableDescriptor desc = new HTableDescriptor(tableName);
for (int i = 0; i < family.length; i++) {
desc.addFamily(new HColumnDescriptor(family[i]));
}
if (admin.tableExists(tableName)) {
System.out.println("table Exists!");
System.exit(0);
} else {
admin.createTable(desc);
System.out.println("create table Success!");
}
}
/*
* 表添加数据
* @rowKey rowKey
* @tableName 表名
* @column1 第一个列族数组 realname
* @value1 第一个列的值的数组
* @column2 第二个列族数组 address
* @value2 第二个列的值的数组
*/
public static void addTableData(String rowKey, String tableName,String[] column1, String[] value1, String[] column2, String[] value2)
throws IOException {
Put put = new Put(Bytes.toBytes(rowKey));
HTable table = (HTable) tablePool.getTable(tableName);
HColumnDescriptor[] columnFamilies = table.getTableDescriptor()
.getColumnFamilies();
for (int i = 0; i < columnFamilies.length; i++) {
String familyName = columnFamilies[i].getNameAsString();
if (familyName.equals("realname")) {
for (int j = 0; j < column1.length; j++) {
put.add(Bytes.toBytes(familyName),Bytes.toBytes(column1[j]), Bytes.toBytes(value1[j]));
}
}
if (familyName.equals("address")) {
for (int j = 0; j < column2.length; j++) {
put.add(Bytes.toBytes(familyName),Bytes.toBytes(column2[j]), Bytes.toBytes(value2[j]));
}
}
}
table.put(put);
}
/*
* 更新表中的某一列
* @tableName 表名
* @rowKey rowKey
* @familyName 列族名
* @columnName 列名
* @value 更新后的值
*/
public static void updateTable(String tableName, String rowKey,
String familyName, String columnName, String value)
throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Put put = new Put(Bytes.toBytes(rowKey));
put.add(Bytes.toBytes(familyName), Bytes.toBytes(columnName),Bytes.toBytes(value));
table.put(put);
System.out.println("update table Success!");
}
/*
* 根据rwokey查询
* @rowKey rowKey
* @tableName 表名
*/
public static Result getResult(String tableName, String rowKey)
throws IOException {
Get get = new Get(Bytes.toBytes(rowKey));
HTable table = (HTable) tablePool.getTable(tableName);
Result result = table.get(get);
for (KeyValue kv : result.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("Timestamp==>" + kv.getTimestamp());
}
return result;
}
/*
* 遍历查询hbase表数组
* @tableName 表名
*/
public static void getResultScann(String tableName) throws IOException {
Scan scan = new Scan();
ResultScanner rs = null;
HTable table = (HTable) tablePool.getTable(tableName);
try {
rs = table.getScanner(scan);
for (Result r : rs) {
for (KeyValue kv : r.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("timestamp==>" + kv.getTimestamp());
}
}
} finally {
rs.close();
}
}
/*
* 查询表中的某单一列
* @tableName 表名
* @rowKey rowKey
*/
public static void getResultByColumn(String tableName, String rowKey,
String familyName, String columnName) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName)); // 获取指定列族以及列中修饰符对应列名
Result result = table.get(get);
for (KeyValue kv : result.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("Timestamp==>" + kv.getTimestamp());
}
}
/*
* 查询某列数据的多个版本
* @tableName 表名
* @rowKey rowKey
* @familyName 列族名
* @columnName 列名
*/
public static void getResultByVersion(String tableName, String rowKey,
String familyName, String columnName) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes(familyName), Bytes.toBytes(columnName));
get.setMaxVersions(5);
Result result = table.get(get);
for (KeyValue kv : result.list()) {
System.out.println("family==>" + Bytes.toString(kv.getFamily()));
System.out.println("qualifier==>" + Bytes.toString(kv.getQualifier()));
System.out.println("value==>" + Bytes.toString(kv.getValue()));
System.out.println("Timestamp==>" + kv.getTimestamp());
}
}
/*
* 删除指定的列
* @tableName 表名
* @rowKey rowKey
* @familyName 列族名
* @columnName 列名
*/
public static void deleteColumn(String tableName, String rowKey,
String falilyName, String columnName) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Delete deleteColumn = new Delete(Bytes.toBytes(rowKey));
deleteColumn.deleteColumns(Bytes.toBytes(falilyName),Bytes.toBytes(columnName));
table.delete(deleteColumn);
System.out.println(falilyName + "==>" + columnName + "is deleted!");
}
/*
* 删除指定的列
* @tableName 表名
* @rowKey rowKey
*/
public static void deleteAllColumn(String tableName, String rowKey) throws IOException {
HTable table = (HTable) tablePool.getTable(tableName);
Delete deleteAll = new Delete(Bytes.toBytes(rowKey));
table.delete(deleteAll);
System.out.println("all columns are deleted!");
}
/*
* 删除表
*
* @tableName 表名
*/
public static void deleteTable(String tableName) throws IOException {
HBaseAdmin admin = new HBaseAdmin(conf);
admin.disableTable(tableName);
admin.deleteTable(tableName);
System.out.println(tableName + " is deleted!");
}
}
package com.yoodb;分享原文地址
public class Test {
public static void main(String[] args) throws Exception {
// 创建表
String tableName = "yoodbblog";
String[] family = { "realname","address" };
HBaseTest.creatTable(tableName,family);
// 为表添加数据
String[] column1 = { "title", "author", "content" };
String[] value1 = {"素文宅","yoodb","www.yoodb.com" };
String[] column2 = { "name", "nickname" };
String[] value2 = { "真实名称", "昵称" };
HBaseTest.addTableData("rowkey1","yoodbblog",column1, value1, column2, value2);
// 删除一列
HBaseTest.deleteColumn("yoodbblog", "rowkey1", "realname", "name");
// 删除所有列
HBaseTest.deleteAllColumn("yoodbblog", "rowkey1");
// 删除表
HBaseTest.deleteTable("yoodbblog");
// 查询
HBaseTest.getResult("yoodbblog", "rowkey1");
// 查询某一列的值
HBaseTest.getResultByColumn("yoodbblog", "rowkey1", "realname", "nickname");
// 修改某一列的值
HBaseTest.updateTable("yoodbblog", "rowkey1", "realname", "nickname","假昵称");
// 遍历表数据查询
HBaseTest.getResultScann("yoodbblog");
// 查询某列的多版本
HBaseTest.getResultByVersion("yoodbblog", "rowkey1", "realname", "name");
}
}
云时代,企业网管前途何在
科技前沿 koyo 发表了文章 0 个评论 2369 次浏览 2015-11-05 18:51
此文献给那些有上进心,但是目前又处在迷茫中的朋友们!希望对你们有用!
当今中国,每年都有超过1000万的大学毕业生从大学校门走向社会面临就业,根据媒体的报道,每年有将近100万大学生找不到工作。在这个激烈竞争的社会,就业真的有那么难吗?尤其是计算机专业毕业的学生,现在北大青鸟,清华万博,乱七八糟的杂牌培训机构遍地开花,如何才能在激烈的竞争中处于不败之地呢?下边我给大家讲讲我的成长道路,希望对你的职业发展有所启发。
2009年7月份,我从北京某不知名大学毕业,毕业的时候,我和大多数的同学一样忙于找工作,每天都要投递大量的简历,结果给我打电话的却少之又少。过了几天,终于等来了电话,是中关村E世界的,当时我应聘的岗位是技术支持工程师,面试的时候,老板和我聊了聊,说他们主要招销售方面的人,就随便问了我一些Windows方面的问题。结果让我回家等通知,等了好久也没有电话。后来又有一家公司给我打电话,我去面试之后,居然是臭名昭著的保险公司(中国平安)。我去面试的时候,那个大姐便开始给我洗脑,说是干保险这个行业是发大财的行业,我说我应聘的是网络工程师,结果被打击了一番。于是我被迫选择在保险公司呆了一个月,这一个月主要是上课,然后考保险人代理证,当时的心态就是,反正先找一个工作干着,不管是什么工作。等到考试的时候,我心里在想,如果考过了,我就认命了,从此就干保险这个行业,如果没有考过,我还是干计算机相关的专业。结果出来的时候,60分及格的成绩我考了58分,果真老天有眼,居然不让我干这个行业。
离开保险公司之后,我就放弃找工作了,每天把自己封闭起来,一心一意地看书,《鸟哥私房菜》,《思科网络技术学院教程 CCNA安全》,《构建高可用集群》,我每天早晨6点就起床看书,做实验,到了9:30,我就坐车去国家图书馆,里边有很多和我专业相关的专业。我连续坚持了一个月,后来通过朋友介绍,我主动去北京工业大学认识了一位老师,和他聊了将近半小时,他建议我考一个行业内的资格证书,然后他私人给我授课,课时是两天,学费是1800,然后考试费是4000多,当时家里给我打的6000块钱,我全部拿出来考试了,以至于后来吃饭都成了问题。因为当时父母的意思就是,你现在已经毕业了,你不能再问家里要钱了。所以每天都只吃一顿饭,当我生存面临问题的时候,我不能坐地等死,而是主动去联系圈子内的同学,朋友帮我找一个能管饭的工作就OK了。就在我去丰台工地工作的第二天,北京工业大学的那个老师给我打电话,说是他手上有一份工作,让我赶紧准备一下去面试,我当天下午就离开工地,去望京那边一家公司面试。面试的时候,是一个和我年龄相仿的人,他也没有问我技术上的问题,毕竟是他老师推荐的人,好意思拒绝嘛?所以第二天就去上班了,我的第一份工作,当时月薪是3500,这和我当时的心理预期值1200相比,还是值得兴奋一下的,当时我的所有同学都在2000以下。后来,我明白了一个道理,只要你想改变,愿意付出代价,你就一定会有回报。给我培训的那个老师拿我的学费,人家心里边自然不会把我放在一边。
工作一年之后,我好不容易工资涨到了4000,但是我开始变得迷茫了,没有刚开始工作时那么卖力了。站在人生的十字路口,我不知道自己的未来到底该走向何方?又一次参加中国交互式设计大赛,我是做现场技术支持的,在场的评委全是全国知名美术学院的教授,一天下来,我们公司作为主办方,给各位教授发红包,里边全是4000块钱,这个价格是在一个项目预算单上看到的,当时心里的落差太大了。我一个月的收入还没有别人一天的收入多,原来这个社会阶级这么明显。那段时间,公司基本上没什么事情,偶尔就是某个人电脑无法上网,新人来了,装装系统,到后来,公司所有的人都认识我了,只要有问题第一个就是想到我,什么插线板不好使,饮水机坏了,厕所堵住了,都会找我,此时我变得有点不耐烦了,原来我真的是一个打杂的,我看上去比谁都忙,但是我的收入比谁都低。
我的青春我做主!我的未来不是梦!哈哈O(∩_∩)O,在心中喊着各种口号,每天爬起来,还是原地踏步走,这样下去肯定会废掉的。与其坐以待毙,不如想个法子提高自己的水平,提高自己的身价。都说人的生命是无价的,但是我想说,每个人的能力是有价的,能力不同,创造的价值也不同。我整天在网上看一些牛人的技术博客,从他们那里学到了很多职业发展的方向。给大家分享一个百度文库《企业网管未来的职业发展》:【http://wenku.baidu.com/view/6f043dd233d4b14e85246888.html】,希望这篇文章对所有刚开始从事IT行业的同学们有一点帮助。结语:
牛人那么多,需要你努力。在互联网风口漂浮大数据的云时代。你不和云沾点边,都不敢说是互联网公司,不敢说是互联网人。监控有云监控、备份有云备份、主机有云主机、存储有云存储等等!云时代企业网管那该何去何从呢???
监控IO脚本
运维 koyo 发表了文章 0 个评论 2425 次浏览 2015-11-05 18:04
#!/bin/sh
/etc/init.d/syslog stop
echo 1 > /proc/sys/vm/block_dump
sleep 60
dmesg | awk '/(READ|WRITE|dirtied)/ {process[$1]++} END {for (x in process) \
print process[x],x}' |sort -nr |awk '{print $2 " " $1}' | \
head -n 10
echo 0 > /proc/sys/vm/block_dump
/etc/init.d/syslog start
nginx负载均衡解释
运维 Geek小A 发表了文章 0 个评论 3136 次浏览 2015-11-03 21:25
一、特点
1.1 应用情况
Nginx做为一个强大的Web服务器软件,具有高性能、高并发性和低内存占用的特点。此外,其也能够提供强大的反向代理功能。俄罗斯大约有超过20%的虚拟主机采用Nginx作为反向代理服务器,在国内也有腾讯、新浪、网易等多家网站在使用Nginx作为反向代理服务器。据Netcraft统计,世界上最繁忙的网站中有11.48%使用Nginx作为其服务器或者代理服务器。基于反向代理的功能,Nginx作为负载均衡主要有以下几点理由:
- []高并发连接[/][]内存消耗少[/][]配置文件非常简单[/][]成本低廉[/][]支持Rewrite重写规则[/][]内置的健康检查功能[/][]节省带宽[/][]稳定性高[/]
nginx在启动后,会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程。工作进程以非特权用户运行。 master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。worker进程则是处理基本的网络事件。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。开发模型:epoll和kqueue。1.2 架构
- []支持的事件机制:kqueue、epoll、rt signals、/dev/poll 、event ports、select以及poll。[/][]支持的kqueue特性包括EV_CLEAR、EV_DISABLE、NOTE_LOWAT、EV_EOF,可用数据的数量,错误代码.[/][]支持sendfile、sendfile64和sendfilev;文件AIO;DIRECTIO;支持Accept-filters和TCP_DEFER_ACCEP.[/]
2.1 协议支持Nginx工作在网络的7层,可以针对http应用本身来做分流策略。支持七层HTTP、HTTPS协议的负载均衡。对四层协议的支持需要第三方插件-yaoweibin的ngx_tcp_proxy_module实现了tcp upstream。https://github.com/yaoweibin/nginx_tcp_proxy_module此外,nginx本身也逐渐在完善对其他协议的支持:二、负载均衡
- []Nginx 1.3.13 开发版支持WebSocket代理。[/][]Nginx 1.3.15开发版支持SPDY。[/]
for(i = 0;i < 3;i++){ hash = (hash * 113 + iphp->addr) % 6271; } p = hash % iphp->rrp.peers->number;从代码中可以看出,hash值既与ip有关又与后端机器的数量有关。经过测试,上述算法可以连续产生1045个互异的value,这是该算法的硬限制。对此nginx使用了保护机制,当经过20次hash仍然找不到可用的机器时,算法退化成轮询。因此,从本质上说,ip hash算法是一种变相的轮询算法,如果两个ip的初始hash值恰好相同,那么来自这两个ip的请求将永远落在同一台服务器上,这为均衡性埋下了很深的隐患。 3、fairfair策略是扩展策略,默认不被编译进nginx内核。其原理是根据后端服务器的响应时间判断负载情况,从中选出负载最轻的机器进行分流。这种策略具有很强的自适应性,但是实际的网络环境往往不是那么简单,因此要慎用。 4、通用hash、一致性hash这两种也是扩展策略,在具体的实现上有些差别,通用hash比较简单,可以以nginx内置的变量为key进行hash,一致性hash采用了nginx内置的一致性hash环,可以支持memcache。
1、HTTP2.2 配置示例
http { upstream www.exmaple.com { server 192.168.1.2:80; server 192.168.1.3:80; } server{ listen 80; server_name www.example.com; location / { proxy_pass http://www.example.com; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /nginx_status { stub_status on; access_log off; allow 192.168.1.1;#设置为可访问该状态信息的ip deny all; } } }2、TCP-ngx_tcp_proxy_module
tcp { upstream cluster { # simple round-robin server 192.168.0.1:80; server 192.168.0.2:80; check interval=3000 rise=2 fall=5 timeout=1000; #check interval=3000 rise=2 fall=5 timeout=1000 type=ssl_hello; #check interval=3000 rise=2 fall=5 timeout=1000 type=http; #check_http_send "GET / HTTP/1.0\r\n\r\n"; #check_http_expect_alive http_2xx http_3xx; } server { listen 8888; proxy_pass cluster; } }
3.1 自身监控内置了对后端服务器的健康检查功能。如果Nginx proxy后端的某台服务器宕机了,会把返回错误的请求重新提交到另一个节点,不会影响前端访问。它没有独立的健康检查模块,而是使用业务请求作为健康检查,这省去了独立健康检查线程,这是好处。坏处是,当业务复杂时,可能出现误判,例如后端响应超时,这可能是后端宕机,也可能是某个业务请求自身出现问题,跟后端无关。3.2 可扩展性Nginx属于典型的微内核设计,其内核非常简洁和优雅,同时具有非常高的可扩展性。如下图所示: Nginx是纯C语言的实现,其可扩展性在于其模块化的设计。目前,Nginx已经有很多的第三方模块,大大扩展了自身的功能。nginx_lua_module可以将Lua语言嵌入到Nginx配置中,从而利用Lua极大增强了Nginx本身的编程能力,甚至可以不用配合其它脚本语言(如PHP或Python等),只靠Nginx本身就可以实现复杂业务的处理。3.3 配置修改nginx的配置架构如下图所示: Nginx支持热部署,几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。能够在不间断服务的情况下,对软件版本进行进行升级。Nginx的配置文件非常简单,风格跟程序一样通俗易懂,能够支持perl语法。使用nginx –s reload可以在运行时加载配置文件,便于运行时扩容/减容。重新加载配置时,master进程发送命令给当前正在运行的worker进程worker进程接到命令后会在处理完当前任务后退出。同时,master进程会启动新的worker进程来接管工作。三、动态负载均衡
4.1 优势[list=1][]可以很好地进行http 的头处理[/][]对http协议以及https的良好支持[/][]有足够的第三方插件供使用[/][]支持热部署,更改后端是平滑的[/]4.2 劣势[list=1][]缺少对session的支持[/][]对四层tcp的支持不够好[/][]post请求写文件系统,造成500 error[/][]缺乏主动的后端服务器健康监测[/][]默认的监控界面统计信息不全[/]四、优势和劣势
5.1 特性[list=1][]继承Nginx-1.2.9的所有特性,100%兼容Nginx的配置;[/][]动态模块加载(DSO)支持。加入一个模块不再需要重新编译整个Tengine;[/][]输入过滤器机制支持。通过使用这种机制Web应用防火墙的编写更为方便;[/][]动态脚本语言Lua支持。扩展功能非常高效简单;[/][]支持管道(pipe)和syslog(本地和远端)形式的日志以及日志抽样;[/][]组合多个CSS、JavaScript文件的访问请求变成一个请求;[/][]更加强大的负载均衡能力,包括一致性hash模块、会话保持模块,还可以对后端的服务器进行主动健康检查,根据服务器状态自动上线下线;[/][]自动根据CPU数目设置进程个数和绑定CPU亲缘性;[/][]监控系统的负载和资源占用从而对系统进行保护;[/][]显示对运维人员更友好的出错信息,便于定位出错机器;[/][]更强大的防攻击(访问速度限制)模块;[/][]更方便的命令行参数,如列出编译的模块列表、支持的指令等;[/][]可以根据访问文件类型设置过期时间;[/]5.2 负载均衡负载均衡方面,Tengine主要有以下几个特点,基本上弥补了 nginx在负载均衡方面的欠缺:[list=1][]支持一致性Hash模块[/][]会话保持模块[/][]对后端服务器的主动健康检查。[/][]增加了请求体不缓存到磁盘的机制[/]五、Tengine
月薪2000和月薪十万的差别,看看你就懂了!
科技前沿 push 发表了文章 0 个评论 4620 次浏览 2015-11-02 12:16
MySQL数据库进行分库备份shell脚本
运维 koyo 发表了文章 0 个评论 2656 次浏览 2015-11-02 11:48
[root@shell scripts]# vi fenbiao_backup.sh分享原文
#!/bin/bash
MysqlUser=root
PassWord=backup123
Port=3306
Socket="/data/$Port/mysql.sock"
MysqlCmd="mysql -u$MysqlUser -p$PassWord -S $Socket"
Database=`$MysqlCmd -e "show databases;"|egrep -v "Database|_schema|mysql"`
MysqlDump="mysqldump -u$MysqlUser -p$PassWord -S $Socket"
IP=`ifconfig eth0|awk -F "[ :]+" 'NR==2 {print $4}'`
BackupDir=/backup/$IP
[ -d $BackupDir ] || mkdir -p $BackupDir
for dbname in $Database
do
[ ! -d /$BackupDir/$dbname ] && mkdir -p /$BackupDir/$dbname
TABLE=`$MysqlCmd -e "show tables from $dbname;"|sed '1d'`
for table in $TABLE
do
$MysqlDump $dbname $table|gzip >/$BackupDir/$dbname/${dbname}_${table}_$(date +%F).sql.gz
done
done
MySQL主从同步延迟原因和解决方法分享
学习资源 koyo 发表了文章 0 个评论 5029 次浏览 2015-11-02 11:34
企业面试题:MySQL出现同步延迟有哪些原因?如何解决?分享原文
1.从库太多导致复制延迟
优化:建议从库数量3-5个为宜
2.从库硬件比主库硬件差
优化:提升硬件性能
3.慢SQL语句过多
优化:SQL语句执行时间太长,需要优化SQL语句
4.主从复制的设计问题
优化:主从复制单线程,可以通过多线程IO方案解决;另外MySQL5.6.3支持多线程IO复制。
5.主从库之间的网络延迟
优化:尽量链路短,提升端口带宽
6.主库读写压力大
优化:前端加buffer和缓存。主从延迟不同步:
不管有多延迟,只要不影响业务就没事
7、业务设计缺陷导致延迟影响业务
优化:从库没有数据改读主库