Redis单线程架构

1 单线程模型

Redis客户端对服务端的每次调用都经历了发送命令,执行命令,返回结果三个过程。其中执行命令阶段,由于Redis是单线程来处理命令的,所有每一条到达服务端的命令不会立刻执行,所有的命令都会进入一个队列中,然后逐个被执行。并且多个客户端发送的命令的执行顺序是不确定的。但是可以确定的是不会有两条命令被同时执行,不会产生并发问题,这就是Redis的单线程基本模型。

2 单线程模型每秒万级别处理能力的原因

(1)纯内存访问。数据存放在内存中,内存的响应时间大约是100纳秒,这是Redis每秒万亿级别访问的重要基础。

(2)非阻塞I/O,Redis采用epoll做为I/O多路复用技术的实现,再加上Redis自身的事件处理模型将epoll中的连接,读写,关闭都转换为了时间,不在I/O上浪费过多的时间。

(3)单线程避免了线程切换和竞态产生的消耗。

(4)Redis采用单线程模型,每条命令执行如果占用大量时间,会造成其他线程阻塞,对于Redis这种高性能服务是致命的,所以Redis是面向高速执行的数据库。

redis为什么要设计成单线程:https://hacpai.com/article/1470967571415

MongoDB中字段的添加与删除

mongoDB添加和删除表中一个字段

使用update命令

update命令格式:

db.collection.update(criteria,objNew,upsert,multi)

参数说明:

criteria:查询条件

objNew:update对象和一些更新操作符

upsert:如果不存在update的记录,是否插入objNew这个新的文档,true为插入,默认为false,不插入。

multi:默认是false,只更新找到的第一条记录。如果为true,把按条件查询出来的记录全部更新。

//例如要把User表中address字段删除
db.User.update({},{$unset:{‘address’:”}},false, true)

参考:https://docs.mongodb.com/manual/reference/method/db.collection.update/#update-parameter

==================

添加一列 $set

//字符类型
db.User.update({},{$set:{‘app_id’:’1′}}, false, true)
//数字类型(double)
db.User.update({},{$set:{‘app_id’:1}}, false, true)

//删除字段 $unset
db.User.update({},{$unset:{‘app_id’:”}}, false, true)

这里使用了mongodb中的修改器 $set 和 $unset, 对于更多的操作符请参考:http://blog.csdn.net/mcpang/article/details/7752736

从PHP客户端看MongoDB通信协议

MongoDB的 PHP 客户端有一个 MongoCursor 类,它是用于获取一次查询结果集的句柄(或者叫游标),这个简单的取数据操作,内部实现其实不是那么简单。本文就通过对 MongoCursor 类一些操作进行分析,向大家揭开 MongoDB 客户端服务器通信的一些内部细节。

getNext与网络请求

通常来说,每一次find操作都会返回一个MongoCursor对象,在这个对象上调用getNext方法,就能够获得一条结果数据。循环调用getNext方法就能获取多条数据。下面我们就来看看其内部取数据的具体逻辑。 Continue reading

MongoDB 客户端 MongoVue

今天在同事那里看到了一个很不错的MongoDB的客户端工具MongoVue,地址是http://www.mongovue.com/。做的不错,1.0版本的开始收费了,费用也不贵才35$。真正需要的同学可以掏点钱买个吧,也算是支持这个工具,如果只是学习研究用的话我这里还有一个0.9.7版本,虽然比起1.0版来说有些bug,平常使用也够了,需要的同学可以单独联系我。

1.0版之后超过15天后功能受限。可以通过删除以下注册表项来解除限制:

[HKEY_CURRENT_USER\Software\Classes\CLSID\{B1159E65-821C3-21C5-CE21-34A484D54444}\4FF78130]

把这个项下的值全删掉就可以了。

Continue reading

Mongodb 与mysql 语法比较

mongodb与mysql命令对比

传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。  Continue reading

MongoDB数据库优化:Mongo Database Profiler

在MySQL中,慢查询日志是经常作为我们优化数据库的依据,那在MongoDB中是否有类似的功能呢?答案是肯定的,那就是Mongo Database Profiler.不仅有,而且还有一些比MySQL的Slow Query Log更详细的信息。它就是我们这篇文章的主题。

  开启 Profiling 功能

有两种方式可以控制 Profiling 的开关和级别,第一种是直接在启动参数里直接进行设置。

启动MongoDB时加上–profile=级别 即可。

也可以在客户端调用db.setProfilingLevel(级别) 命令来实时配置。可以通过db.getProfilingLevel()命令来获取当前的Profile级别。 Continue reading

Mongodb亿级数据量的性能测试

进行了一下Mongodb亿级数据量的性能测试,分别测试如下几个项目:

 (所有插入都是单线程进行,所有读取都是多线程进行)

1) 普通插入性能 (插入的数据每条大约在1KB左右)

2) 批量插入性能 (使用的是官方C#客户端的InsertBatch),这个测的是批量插入性能能有多少提高

3) 安全插入功能 (确保插入成功,使用的是SafeMode.True开关),这个测的是安全插入性能会差多少

4) 查询一个索引后的数字列,返回10条记录(也就是10KB)的性能,这个测的是索引查询的性能

5) 查询两个索引后的数字列,返回10条记录(每条记录只返回20字节左右的2个小字段)的性能,这个测的是返回小数据量以及多一个查询条件对性能的影响

6) 查询一个索引后的数字列,按照另一个索引的日期字段排序(索引建立的时候是倒序,排序也是倒序),并且Skip100条记录后返回10条记录的性能,这个测的是Skip和Order对性能的影响

7) 查询100条记录(也就是100KB)的性能(没有排序,没有条件),这个测的是大数据量的查询结果对性能的影响

8) 统计随着测试的进行,总磁盘占用,索引磁盘占用以及数据磁盘占用的数量

并且每一种测试都使用单进程的Mongodb和同一台服务器开三个Mongodb进程作为Sharding(每一个进程大概只能用7GB左右的内存)两种方案

其实对于Sharding,虽然是一台机器放3个进程,但是在查询的时候每一个并行进程查询部分数据,再有运行于另外一个机器的mongos来汇总数据,理论上来说在某些情况下性能会有点提高 Continue reading

mongodb索引讲解与性能调优

mongodb索引规则基本上与传统的关系库一样,大部分优化MySQL/Oracle/SQLite索引的技巧也适用于mongodb。

一、 为什么用索引:

当查询中用到某些条件时,可以对该键建立索引,以提高查询速度。

如果数据量很多且查询多于更新时,可以用索引提高查询的速度。

二、 索引管理:

a)         查询索引:

  1. 查询已有索引的明细:

查询索引很简单,比如说需要查询mailaccess数据库中的Mail collection上的索引时:

mongo                          进入mongo

MongoDB shell version: 1.8.1

connecting to: test

> use mailaccess                  进入mailaccess database

switched to db mailaccess

> db.Mail.getIndexes()             查询索引明细

[

{

“name” : “_id_”,

“ns” : “mailaccess.Mail”,

“key” : {

“_id” : 1

},

“v” : 0

},

{

“_id” : ObjectId(“4df063ac48857df7ac35c348”),

“ns” : “mailaccess.Mail”,

“key” : {

“user” : 1,

“folderId” : 1,

“mailfilename” : 1

},

“name” : “user_1_folderId_1_mailfilename_1”,

“v” : 0

},

…… Continue reading