mongodb的监控与性能优化

in nosql

一.mongodb的监控

mongostat是mongdb自带的状态检测工具,在命令行下使用。它会间隔固定时间获取mongodb的当前运行状态,并输出。如果你发现数据库突然变慢或者有其他问题的话,你第一手的操作就考虑采用mongostat来查看mongo的状态。

立方图片分享

它的输出有以下几列:

  • inserts/s 每秒插入次数
  • query/s 每秒查询次数
  • update/s 每秒更新次数
  • delete/s 每秒删除次数
  • getmore/s 每秒执行getmore次数
  • command/s 每秒的命令数,比以上插入、查找、更新、删除的综合还多,还统计了别的命令
  • flushs/s 每秒执行fsync将数据写入硬盘的次数。
  • mapped/s 所有的被mmap的数据量,单位是MB,
  • vsize 虚拟内存使用量,单位MB
  • res 物理内存使用量,单位MB
  • faults/s 每秒访问失败数(只有Linux有),数据被交换出物理内存,放到swap。不要超过100,否则就是机器内存太小,造成频繁swap写入。此时要升级内存或者扩展
  • locked % 被锁的时间百分比,尽量控制在50%以下吧
  • idx miss % 索引不命中所占百分比。如果太高的话就要考虑索引是不是少了
  • q t|r|w 当Mongodb接收到太多的命令而数据库被锁住无法执行完成,它会将命令加入队列。这一栏显示了总共、读、写3个队列的长度,都为0的话表示mongo毫无压力。高并发时,一般队列值会升高。
  • conn 当前连接数
  • time 时间戳

二.mongodb的优化

mongodb可以通过profile来监控数据,进行优化。

Continue Reading »

0 Comments

Mongdb监控 (MMS)

in nosql

MMS (MongoDB Monitoring Service) is a hosted application created by 10gen for monitoring MongoDB deployments. MMS Collects statistics on all key server and hardware indicators and presents this data through an intuitive web interface

先简单说下原理:

1、在mms服务器上添加mongodb服务器的ip,端口,user,password.
2、在mongodb服务器所在的内网空闲机器上安装定制的agent脚本。
3、agent脚本从mms获取你的服务器Ip及端口等信息,然后连接到mongodb服务器获取必要的监控数据。
4、agent脚本将监控信息上传到mms服务器,我们登陆后就可以查看到相应的信息了。

主页地址如下

1.https://mms.10gen.com/help/install.html

在Hosts项上点击添加,此处hostname填写内网IP,port为mongodb端口,user/password为用户名和密码。

Continue Reading »

0 Comments

nginx: [warn] the "log_format" directive may be used only on "http" level ...解决办法

in 服务器类

新开了一个vps,装了最新的nginx 1.0.2版本,将原来的虚拟主机配置直接拿过来.用nginx -t 测试语法的时候,发现提示以下警告信息

[root@centos nginx]# ./sbin/nginx -t
nginx: [warn] the "log_format" directive may be used only on "http" level in /usr/local/nginx/conf/vhosts/bbs.conf:62

解决办法如下:

将/usr/local/nginx/conf/nginx.conf 里server段里的下面代码移出放到该server段的前面即可。

log_format  access  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_x_forwarded_for';

如果有其的虚拟主机开启了日志,也按上面的要求移出server段放在server段的前面即可。

/usr/local/nginx/sbin/nginx -t 测试一下,没有warn警告信息了。

[root@centos vhosts]# ../../sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@centos vhosts]#

0 Comments

三招解决MongoDB的磁盘IO问题

in nosql

有点标题党的意思,不过下面三招确实比较实用,内容来自Conversocial公司的VP Colin Howe在London MongoDB用户组的一个分享。
申请:下面几点并非放四海皆准的法则,具体是否能够使用,还需要根据自己的应用场景和数据特点来决定。

1.使用组合式的大文档
我们知道MongoDB是一个文档数据库,其每一条记录都是一个JSON格式的文档。比如像下面的例子,每一天会生成一条这样的统计数据:

{ metric: "content_count", client: 5, value: 51, date: ISODate("2012-04-01 13:00") }
{ metric: "content_count", client: 5, value: 49, date: ISODate("2012-04-02 13:00") }

而如果采用组合式大文档的话,就可以这样将一个月的数据全部存到一条记录里:

{ metric: "content_count", client: 5, month: "2012-04", 1: 51, 2: 49, ... }

通过上面两种方式存储,预先一共存储大约7GB的数据(机器只有1.7GB的内存),测试读取一年信息,这二者的读性能差别很明显:

Continue Reading »

1 Comment

linux tcpdump命令参数及用法详解--linux下抓包网络分析

in 服务器类

采用命令行方式,它的命令格式为:

tcpdump [ -adeflnNOpqStvx ] [ -c 数量 ] [ -F 文件名 ][ -i 网络接口 ] [ -r 文件名] [ -s snaplen ][ -T 类型 ] [ -w 文件名 ] [表达式 ]

1. tcpdump的选项介绍
-a    将网络地址和广播地址转变成名字;
-d    将匹配信息包的代码以人们能够理解的汇编格式给出;
-dd    将匹配信息包的代码以c语言程序段的格式给出;
-ddd    将匹配信息包的代码以十进制的形式给出;
-e    在输出行打印出数据链路层的头部信息;
-f    将外部的Internet地址以数字的形式打印出来;
-l    使标准输出变为缓冲行形式;
-n    不把网络地址转换成名字;
-t    在输出的每一行不打印时间戳;
-v    输出一个稍微详细的信息,例如在ip包中可以包括ttl和服务类型的信息;
-vv    输出详细的报文信息;
-c    在收到指定的包的数目后,tcpdump就会停止;
-F    从指定的文件中读取表达式,忽略其它的表达式;
-i    指定监听的网络接口;
-r    从指定的文件中读取包(这些包一般通过-w选项产生);
-w    直接将包写入文件中,并不分析和打印出来;
-T    将监听到的包直接解释为指定的类型的报文,常见的类型有rpc (远程过程调用)和snmp(简单网络管理协议;)

Continue Reading »

0 Comments

[教程]mongodb常用维护命令

in nosql

1.客户端常用命令
   #mongo
  >help                       //列出帮助
  >db.help()                //db级别的帮助
>db.mycollection.help()  //collection 级别的帮助

  常用命令:
  >show dbs                     //show database names
  >show collections          //show collections in current database
  >use <db_name>          //set current database
  >db.foo.find()                //list objects in collection foo
  >db.foo.find({a:1})        //list objects in foo where a == 1
  >db.createCollection(name, { size : ..., capped : ..., max : ... } )   //创建collection
  >db.dropDatabase()    //删除库
  >db.collection.count()  //统计colleciton的数量
  >db.collection.drop()    //删除此colleciton
  >db.foo.find().count     //某个数据的数量
  >db.collection.find(...).limit(n)

MongoDB与MySQL的对应关系如下表所示:

Continue Reading »

0 Comments

MongoDB之导入和导出

in nosql

在上文中,我们了解了教你如何利用MySQL学习MongoDB之授权和权限,本文中我们继续我们的学习之旅,学习两者的导入和导出

1、MySQL导入和导出

(1)、mysqlimport

此工具位于mysql/bin目录中,是MySQL的一个载入(或者说导入)数据的一个非常有效的工具。这是一个命令行工具。有两个参数以及大量的选项可供选择。这个工具把一个文本文件(text file)导入到你指定的数据库和表中。比方说我们要从文件student.txt中把数据导入到数据库class中的表 student中:

mysqlimport class.student student.txt

(2)、load data infile

这个命令与mysqlimport非常相似,但这个方法可以在MySQL命令行中使用。 如mysqlimport工具一样,这个命令也有一些可以选择的参数。比如您需要把自己的电脑上的数据导入到远程的数据库服务器中,您可以使用下面的命令:

Load data local infile "d:\student.txt" into table student;

Continue Reading »

0 Comments

MongoDB非正常关闭后修复记录 mongod --repair

in nosql

mongod没有后台执行,在终端连接非正常断开后,再次执行mongod报错,如下所示:

[root@localhost mongodb]# ./bin/mongod
./bin/mongod --help for help and startup options
Thu Nov 17 22:42:49
Thu Nov 17 22:42:49 warning: 32-bit servers don't have journaling enabled by default. Please use --journal if you want durability.
Thu Nov 17 22:42:49
Thu Nov 17 22:42:49 [initandlisten] MongoDB starting : pid=3257 port=27017 dbpath=/data/db/ 32-bit host=localhost
Thu Nov 17 22:42:49 [initandlisten]
Thu Nov 17 22:42:49 [initandlisten] ** NOTE: when using MongoDB 32 bit, you are limited to about 2 gigabytes of data
Thu Nov 17 22:42:49 [initandlisten] **       see http://blog.mongodb.org/post/137788967/32-bit-limitations
Thu Nov 17 22:42:49 [initandlisten] **       with --journal, the limit is lower
Thu Nov 17 22:42:49 [initandlisten]
Thu Nov 17 22:42:49 [initandlisten] db version v2.0.1, pdfile version 4.5
Thu Nov 17 22:42:49 [initandlisten] git version: 3a5cf0e2134a830d38d2d1aae7e88cac31bdd684
Thu Nov 17 22:42:49 [initandlisten] build info: Linux domU-12-31-39-01-70-B4 2.6.21.7-2.fc8xen #1 SMP Fri Feb 15 12:39:36 EST 2008 i686 BOOST_LIB_VERSION=1_41
Thu Nov 17 22:42:49 [initandlisten] options: {}
**************
Unclean shutdown detected.
Please visit http://dochub.mongodb.org/core/repair for recovery instructions.
*************
Thu Nov 17 22:42:49 [initandlisten] exception in initAndListen: 12596 old lock file, terminating
Thu Nov 17 22:42:49 dbexit:
Thu Nov 17 22:42:49 [initandlisten] shutdown: going to close listening sockets...
Thu Nov 17 22:42:49 [initandlisten] shutdown: going to flush diaglog...
Thu Nov 17 22:42:49 [initandlisten] shutdown: going to close sockets...
Thu Nov 17 22:42:49 [initandlisten] shutdown: waiting for fs preallocator...
Thu Nov 17 22:42:49 [initandlisten] shutdown: closing all files...
Thu Nov 17 22:42:49 [initandlisten] closeAllFiles() finished
Thu Nov 17 22:42:49 dbexit: really exiting now

 

修复方法:

这算是一个Mongod 启动的一个常见错误,非法关闭的时候,lock 文件没有干掉,第二次启动的时候检查到有lock 文件的时候,就报这个错误了。

Continue Reading »

0 Comments

jquery.validate remote 和 自定义验证方法

in js框架

$(function(){

var validator = $("#enterRegForm").validate({
debug:false, //调试模式取消submit的默认提交功能
//errorClass: "error",//默认为错误的样式类为:error
//validClass: "check",//验证成功后的样式,默认字符串valid
focusInvalid: true,//表单提交时,焦点会指向第一个没有通过验证的域
//focusCleanup:true;//焦点指向错误域时,隐藏错误信息,不可与focusInvalid一起使用!
onkeyup: true,
errorElement: "div",
submitHandler: function(form){ //表单提交句柄,为一回调函数,带一个参数:form
form.submit(); //提交表单
},

rules: {
"enterprise.enName": {
required: true,
minlength: 6,
remote:{
url: "/nameServlet",     //后台处理程序
type: "get",               //数据发送方式
dataType: "json",           //接受数据格式
data: {                     //要传递的数据
enName: function() {
return $("#enName").val();
}
}

}
},

"user.passWord":{
required:true,
rangelength:[6,18]
},
passWordConf:{
required:true,
rangelength:[6,18],
equalTo:"#passWord" //此处的passWord 是<input id="passWord"> 一开始还以为是name的值呢,气死了
}

},

messages: { //自定义验证消息
"enterprise.enName": {
required: "请填写企业名称!",
minlength: $.format("至少要{0}个字符!"),
remote:$.format("该企业名称已存在!")

},
"user.passWord":{
required:"请填写确认密码!",
rangelength:$.format("密码要在{0}-{1}个字符之间!")
},
passWordConf:{
required:"请填写确认密码!",
rangelength:$.format("确认密码要在{0}-{1}个字符之间!"),
equalTo:"确认密码要和密码一致!"
},

errorPlacement: function(error, element) { //验证消息放置的地方
//error.appendTo( element.parent("td").next("td").children(".msg") );
error.appendTo( element.parent(".field").next("div"));
},
highlight: function(element, errorClass) { //针对验证的表单设置高亮
$(element).addClass(errorClass);
},
success: function(div) {
div.addClass("valid");
}
});

});

自定义方法;

新建一个js文件:$(document).ready(function(){
// 字符最小长度验证(一个中文字符长度为2)
jQuery.validator.addMethod("stringMinLength", function(value, element, param) {
var length = value.length;
for ( var i = 0; i < value.length; i++) {
if (value.charCodeAt(i) > 127) {
length++;
}
}
return this.optional(element) || (length >= param);
}, $.validator.format("长度不能小于{0}!"));

// 字符最大长度验证(一个中文字符长度为2)
jQuery.validator.addMethod("stringMaxLength", function(value, element, param) {
var length = value.length;
for ( var i = 0; i < value.length; i++) {
if (value.charCodeAt(i) > 127) {
length++;
}
}
return this.optional(element) || (length <= param);
}, $.validator.format("长度不能大于{0}!"));

// 字符验证
jQuery.validator.addMethod("stringCheck", function(value, element) {
return this.optional(element) || /^[\u0391-\uFFE5\w]+$/.test(value);
}, "只能包括中文字、英文字母、数字和下划线");

// 中文字两个字节
jQuery.validator.addMethod("byteRangeLength", function(value, element, param) {
var length = value.length;
for(var i = 0; i < value.length; i++){
if(value.charCodeAt(i) > 127){
length++;
}
}
return this.optional(element) || ( length >= param[0] && length <= param[1] );
}, "请确保输入的值在3-15个字节之间(一个中文字算2个字节)");

// 字符验证
jQuery.validator.addMethod("string", function(value, element) {
return this.optional(element) || /^[\u0391-\uFFE5\w]+$/.test(value);
}, "不允许包含特殊符号!");
// 必须以特定字符串开头验证
jQuery.validator.addMethod("begin", function(value, element, param) {
var begin = new RegExp("^" + param);
return this.optional(element) || (begin.test(value));
}, $.validator.format("必须以 {0} 开头!"));
// 验证两次输入值是否不相同
jQuery.validator.addMethod("notEqualTo", function(value, element, param) {
return value != $(param).val();
}, $.validator.format("两次输入不能相同!"));
// 验证值不允许与特定值等于
jQuery.validator.addMethod("notEqual", function(value, element, param) {
return value != param;
}, $.validator.format("输入值不允许为{0}!"));

// 验证值必须大于特定值(不能等于)
jQuery.validator.addMethod("gt", function(value, element, param) {
return value > param;
}, $.validator.format("输入值必须大于{0}!"));

// 验证值小数位数不能超过两位
jQuery.validator.addMethod("decimal", function(value, element) {
var decimal = /^-?\d+(\.\d{1,2})?$/;
return this.optional(element) || (decimal.test(value));
}, $.validator.format("小数位数不能超过两位!"));
//字母数字
jQuery.validator.addMethod("alnum", function(value, element) {
return this.optional(element) || /^[a-zA-Z0-9]+$/.test(value);
}, "只能包括英文字母和数字");
// 汉字
jQuery.validator.addMethod("chcharacter", function(value, element) {
var tel = /^[\u4e00-\u9fa5]+$/;
return this.optional(element) || (tel.test(value));
}, "请输入汉字");
// 身份证号码验证
jQuery.validator.addMethod("isIdCardNo", function(value, element) {
return this.optional(element) || /^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$/.test(value)||/^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[A-Z])$/.test(value);
}, "请正确输入您的身份证号码");

// 手机号码验证
jQuery.validator.addMethod("isMobile", function(value, element) {
var length = value.length;
var mobile = /^(((13[0-9]{1})|(15[0-9]{1}))+\d{8})$/;
return this.optional(element) || (length == 11 && mobile.test(value));
}, "请正确填写您的手机号码");

// 电话号码验证
jQuery.validator.addMethod("isTel", function(value, element) {
var tel = /^\d{3,4}-?\d{7,9}$/;    //电话号码格式010-12345678
return this.optional(element) || (tel.test(value));
}, "请正确填写您的电话号码");

// 联系电话(手机/电话皆可)验证
jQuery.validator.addMethod("isPhone", function(value,element) {
var length = value.length;
var mobile = /^(((13[0-9]{1})|(15[0-9]{1}))+\d{8})$/;
var tel = /^\d{3,4}-?\d{7,9}$/;
return this.optional(element) || (tel.test(value) || mobile.test(value));

}, "请正确填写您的联系电话");

// 邮政编码验证
jQuery.validator.addMethod("isZipCode", function(value, element) {
var tel = /^[0-9]{6}$/;
return this.optional(element) || (tel.test(value));
}, "请正确填写您的邮政编码");

});

该文件要先被引用再对form进行验证。

注意:remote 中的url 为servlet,但是这个servlet该怎么写呢

一开始以为是跟平时的一样:out.println("用户名"+name+"已存在!");

虽然可以验证,但是还是存在问题:输入个不存在的name还是提示存在。

后来还是Google,看到别人也是犯了这样的错误,解决方法时返回true,false.

但是 doGet 是void类型的,return true 是行不通的。

后来又请教群里的高手,正确写法是out.println("true");就可以了。

哎,费了老长时间

总算是把问题给解决了。

转自:http://hi.baidu.com/iamgongjunhao/blog/item/7c32590e3747abfa36d122b3.html

0 Comments

Zend_Filters_Input来实现对密码重复验证

in 程序开发

22.5.4.  使用 Metacommands 来控制过滤器或校验器规则

除了声明从字段到过滤器或校验器的映射,你可以在数组声明中指定一些 "metacommands" ,开控制一些 Zend_Filter_Input 的可选的行为。 Metacommands 在给定的过滤器或校验器数组值里以字符串索引条目的形式出现。

22.5.4.1. The FIELDS metacommand

如果过滤器或校验器的规则名和需要应用规则的字段名不同,可以用 'fields' metacommand 来指定字段名。

可以用类常量 Zend_Filter_Input::FIELDS 而不是字符串来指定这个 metacommand。

Continue Reading »

0 Comments