月度归档:七月 2013

让进程在后台可靠运行的几种方法

几年前在developerWorks上面看到的文章,感觉非常实用,又简单整理了一下,转到这里,希望给看到的人带来一些帮助。文中提到的nohup和subshell方式一直在使用。

我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败。如何让命令提交后不受本地关闭终端窗口/网络断开连接的干扰呢?下面举了一些例子, 您可以针对不同的场景选择不同的方式来处理这个问题。

如果只是临时有一个命令需要长时间运行,什么方法能最简便的保证它在后台稳定运行呢?

解决方法:

1.nohup
我们知道,当用户注销(logout)或者网络断开时,终端会收到HUP(hangup)信号从而关闭其所有子进程。因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。

HANGUP名称的来由,在Unix的早期版本中,每个终端都会通过modem 和系统通讯。当用户 logout 时,modem 就会挂断(hang up)电话。 同理,当modem断开连接时,就会给终端发送hangup信号来通知其关闭所有子进程。

nohup 无疑是我们首先想到的办法。顾名思义,nohup 的用途就是让提交的命令忽略 hangup 信号。让我们先来看一下 nohup 的帮助信息:

NOHUP(1)                        User Commands                        NOHUP(1)
NAME
nohup – run a command immune to hangups, with output to a non-tty

SYNOPSIS
nohup COMMAND [ARG]…
nohup OPTION

DESCRIPTION
Run COMMAND, ignoring hangup signals.
–help display this help and exit
–version output version information and exit

可见,nohup 的使用是十分方便的,只需在要处理的命令前加上 nohup 即可,标准输出和标准错误缺省会被重定向到 nohup.out 文件中。一般我们可在结尾加上“&”来将命令同时放入后台运行,也可用”>filename 2>&1″来更改缺省的重定向文件名。

nohup 示例

[root@pvcent107 ~]# nohup ping www.ibm.com &; 
[1] 3059 nohup: appending output to `nohup.out' 
[root@pvcent107 ~]# ps -ef |grep 3059 
root 3059 984 0 21:06 pts/3 00:00:00 ping www.ibm.com 
root 3067 984 0 21:06 pts/3 00:00:00 grep 3059 
[root@pvcent107 ~]#

 

2.setsid

nohup 无疑能通过忽略 HUP 信号来使我们的进程避免中途被中断,但如果我们换个角度思考,如果我们的进程不属于接受 HUP 信号的终端的子进程,那么自然也就不会受到 HUP 信号的影响了。setsid 就能帮助我们做到这一点。让我们先来看一下 setsid 的帮助信息:

SETSID(8)                 Linux Programmer’s Manual                 SETSID(8)

NAME

setsid – run a program in a new session

SYNOPSIS

setsid program [ arg … ]

DESCRIPTION

setsid runs a program in a new session.

可见 setsid 的使用也是非常方便的,也只需在要处理的命令前加上 setsid 即可。

setsid 示例

[root@pvcent107 ~]# setsid ping www.ibm.com 
[root@pvcent107 ~]# ps -ef |grep www.ibm.com 
root 31094 1 0 07:28 ? 00:00:00 ping www.ibm.com 
root 31102 29217 0 07:29 pts/4 00:00:00 grep www.ibm.com 
[root@pvcent107 ~]#

 

值得注意的是,上例中我们的进程 ID(PID)为31094,而它的父 ID(PPID)为1(即为 init 进程 ID),并不是当前终端的进程 ID。请将此例与nohup 例中的父 ID 做比较。

3.&符号(命令简单易记,推荐使用。)

这里还有一个关于 subshell 的小技巧。我们知道,将一个或多个命令包含在“()”中就能让这些命令在子 shell 中运行中,从而扩展出很多有趣的功能,我们现在要讨论的就是其中之一。

当我们将”&”也放入“()”内之后,我们就会发现所提交的作业并不在作业列表中,也就是说,是无法通过jobs来查看的。让我们来看看为什么这样就能躲过 HUP 信号的影响吧。

subshell 示例

[root@pvcent107 ~]# (ping www.ibm.com &;) 

[root@pvcent107 ~]# ps -ef |grep www.ibm.com 
root 16270 1 0 14:13 pts/4 00:00:00 ping www.ibm.com 
root 16278 15362 0 14:13 pts/4 00:00:00 grep www.ibm.com 
[root@pvcent107 ~]#

 

从上例中可以看出,新提交的进程的父 ID(PPID)为1(init 进程的 PID),并不是当前终端的进程 ID。因此并不属于当前终端的子进程,从而也就不会受到当前终端的 HUP 信号的影响了。

我们已经知道,如果事先在命令前加上 nohup 或者 setsid 就可以避免 HUP 信号的影响。但是如果我们未加任何处理就已经提交了命令,该如何补救才能让它避免 HUP 信号的影响呢?

解决方法:

 

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 2票) Loading ... Loading ... | 归档目录:实用脚本, 软件技术 | 标签: , , , , |

12款强大的Chrome插件

Chrome功能强大,也得益于其拥有丰富的扩展资源库。Chrome Web Store里有各种各样的插件,Google Store可以满足你使用Chrome时的各种要求。和Firefox一样,Chrome的扩展非常容易安装,而且非常容易卸载。与Firefox不同,Chrome的扩展不需要重新启动,并且不会有扩展插件会减小你的网页面积。在这里我总结出2013年 Chrome 的12款非常强大的扩展程序,供大家挑选分享。这些插件能不同程度地提升效率。诸如Turn off the light这些非常常用的我就不介绍了。

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 2票) Loading ... Loading ... | 归档目录:移动互联 | 标签: , |

Windows XP不能向VMware虚拟机传输大文件的问题分析和解决

不知道从什么时候开始,XP不能向虚拟机传送大文件了,包括借助于vmtools、sftp、samba和ftp都不行,无论哪一段作服务端,都是一样。samba最后的提示是“文件路径太深”。显然不是因为这个原因。使用sftp或者ftp,一般是文件名创建成功后,数据传不出去。如下图:

阅读全文 »

| 1 分2 分3 分4 分5 分 (5.00- 4票) Loading ... Loading ... | 归档目录:软件技术 | 标签: , , , |

DRBD源码分析(一)——内核模块初始化

本地安装的是drbd-8.3.5版本,下载相应的源码包。两个子目录涉及源代码,其中drbd目录为内核态的源码,user目录为用户态工具的源码。所有的业务都是在内核态完成,用户态只是提供工具安装、配置、维护内核模块的工作。

drbd架构图,在官方网站的主页上面就能看到,非常显眼,这是内核态的架构示意图:

wps_clip_image-31087

可以很清晰的看到,drbd在文件系统之下,直接操纵物理磁盘(块设备),在网络模型中,基于传输层之上建立虚拟设备。通过TCP/IP协议与远端设备交互。

drbd内核模块的名字为:

[root@Shentar /opt/drbd-8.3.5]# modprobe -all|grep drbd
/lib/modules/2.6.25-14.fc9.i686/kernel/drivers/block/drbd.ko
[root@Shentar /opt/drbd-8.3.5]#

首先找代码的入口,内核模块的初始化定义:module_init宏定义。在drbd_main.c文件中。


module_init(drbd_init)
module_exit(drbd_cleanup)

下面贴出初始化函数:drbd_init(void):

整个初始化分如下几个步骤:

int __init drbd_init(void)
{
int err;

if (sizeof(struct p_handshake) != 80)
{
printk(KERN_ERR
"drbd: never change the size or layout "
"of the HandShake packet.\n");
return -EINVAL;
}

if (1 > minor_count || minor_count > 255)
{
printk(KERN_ERR
"drbd: invalid minor_count (%d)\n", minor_count);
#ifdef MODULE
return -EINVAL;
#else
minor_count = 8;
#endif
}

err = drbd_nl_init();
if (err)
return err;

err = register_blkdev(DRBD_MAJOR, "drbd");
if (err)
{
printk(KERN_ERR
"drbd: unable to register block device major %d\n", DRBD_MAJOR);
return err;
}

register_reboot_notifier(&drbd_notifier);

/*
* allocate all necessary structs
*/
err = -ENOMEM;

init_waitqueue_head(&drbd_pp_wait);

drbd_proc = NULL; /* play safe for drbd_cleanup */
minor_table = kzalloc(sizeof(struct drbd_conf *) * minor_count, GFP_KERNEL);
if (!minor_table)
goto Enomem;

err = drbd_create_mempools();
if (err)
goto Enomem;

drbd_proc = proc_create("drbd", S_IFREG | S_IRUGO, NULL, &drbd_proc_fops);
if (!drbd_proc)
{
printk(KERN_ERR "drbd: unable to register proc file\n");
goto Enomem;
}

rwlock_init(&global_state_lock);

printk(KERN_INFO "drbd: initialized. "
"Version: " REL_VERSION " (api:%d/proto:%d-%d)\n",
API_VERSION, PRO_VERSION_MIN, PRO_VERSION_MAX);
printk(KERN_INFO "drbd: %s\n", drbd_buildtag());
printk(KERN_INFO "drbd: registered as block device major %d\n", DRBD_MAJOR);
printk(KERN_INFO "drbd: minor_table @ 0x%p\n", minor_table);

return 0; /* Success! */

Enomem : drbd_cleanup();
if (err == -ENOMEM)
/* currently always the case */
printk(KERN_ERR "drbd: ran out of memory\n");
else
printk(KERN_ERR "drbd: initialization failure\n");
return err;
}

  • 1、drbd_nl_init方法

初始化网络,在内核2.6.16之前的版本中,还没有内核连接器的封装,还是直接调用原始的netlink套接字,因此初始化时需要有一系列的初始化netlink的动作。新的内核版本中集成了connector的封装,相对来说网络初始化的过程就简单多了。在分析代码时,需要注意,drbd目录下也有一个connector.c,这是为老版本准备的。新版本中根本没有编译该文件,因此只需要知道cn_add_callback这个接口的作用,而不需要去看connector.c中该函数的定义。昨天误分析到connector.c中去了,发现cn_add_callback函数最终结束时会往自己生成的任务队列中注册一个任务,但是怎么也找不到之后谁来等待执行该任务,试图加日志查看该函数流程时,才发现原来并没有运行到该代码。这才发现上述connector封装的问题。

关于连接器,这里简要说明一下,连接器封装了内核态和用户态的通讯过程。提供了简单的几个接口:

int cn_add_callback(struct cb_id*, char*, void (*callback) (void*));
void cn_del_callback(struct cb_id*);
int cn_netlink_send(struct cn_msg*, u32, gfp_t);

int cn_queue_add_callback(struct cn_queue_dev* dev, char* name,
struct cb_id* id, void (*callback) (void*));
void cn_queue_del_callback(struct cn_queue_dev* dev, struct cb_id* id);

struct cn_queue_dev* cn_queue_alloc_dev(char* name, struct sock*);
void cn_queue_free_dev(struct cn_queue_dev* dev);

int cn_cb_equal(struct cb_id*, struct cb_id*);

void cn_queue_wrapper(void* data);

这里只分析cn_add_callback和cn_netlink_send两个,在内核创建连接器时,需要调用cn_add_callback方法,其中callback函数指针参数指定了连接器接收到数据时的回调函数,数据到达时将由该函数来处理。连接器既可以用于接收数据也可以用于发送数据。接收数据使用回调来处理。发送数据直接使用cn_netlink_send方法即可。该方法支持单播、广播和组播。一般单播和广播会用到。cn_add_callback方法无误返回,也就意味着网络初始化好了,比起之前版本中的复杂创建、绑定和监听套接字等流程简单多了。

  • 2、register_blkdev方法

wps_clip_image-6088

这个方法是内核系统调用,用于注册一个块设备,需要指定主设备号,如果指定的设备号为0,则会由系统自动分配一个。该方法调用之后,就可以在/proc/devices文件中看到drbd块设备。drbd设备的设备号在代码中写死,为147。需要注意的是,如果块设备号已被占用,会导致注册失败。

见左图。

 

 

 

 

  • 3、register_reboot_notifier注册块设备重启时的回调函数

目前注册了一个空函数,委婉的说以后会实现,其实没有任何需要做的事情:

reboot_callback

  • 4、init_waitqueue_head初始化一个等待队列

等待队列可以是生产者和消费者之间的共享队列,后面的业务分析中应该会遇到该结构,到时会仔细分析该队列中所存放的内容。应该与具体的读写数据业务有关。

  • 5、drbd_create_mempools创建内存池

这块还没有仔细分析,drbd中需要使用的内存池特别多,数据块的,接收缓冲区的,发送缓冲区的。

  • 6、proc_create创建/proc/drbd文件

内核允许模块在/proc目录下创建自己的虚拟文件和虚拟文件夹。并且指定该文件的操作回调函数。其中,drbd指定了open, read, write和close方法的回调函数即/proc/drbd的四个回调函数:

struct file_operations drbd_proc_fops =
{
.owner = THIS_MODULE, .open = drbd_proc_open, .read = seq_read,
.llseek = seq_lseek, .release = single_release,
};

在打开该文件时,内核会调用drbd_proc_open函数来呈现相应的内容。也可以说这里是drbd内核服务向用户态反馈信息的一个通道。所有用户态的工具也是基于这个来判断当前drbd的状态。

  • 7、rwlock_init初始化全局读写锁。

整个内核模块的初始化到这里就结束了,总结一下,主要涉及下面几个系统调用:cn_add_callback,cn_netlink_send,register_blkdev,register_reboot_notifier,init_waitqueue_head,mempool_create,create_proc_entry。随着linux 内核的不断壮大,驱动编程似乎也在越来越简单。

| 1 分2 分3 分4 分5 分 (4.89- 9票) Loading ... Loading ... | 归档目录:C/C++, DRBD | 标签: |

WordPress博客添加“返回顶部”按钮

“返回顶部”在网页页面上非常实用。一般主题都没有自带该按钮。可以自己DIY一个。

添加步骤,打开博客的后台管理,依次进入“外观”,“编辑”,打开“footer.php”,在最后一个</div>与</body>之间添加如下代码,注意替换图片地址(斜体部分)以匹配特定主题。

<div id="full" style="width:88px; height:88px; position:fixed; right:0px; 
    bottom:0px; margin-left:0px; margin-bottom:0px; z-index:100; text-align:center; cursor:pointer;">
  <a>
    <img src="http://shentar.qiniudn.com/wp-content/themes/thematic/gallery/totop2.png"
    border=0 width="55px" width="55px" alt="返回顶部">
  </a>
</div>
<script type="text/javascript">
  var isie6 = window.XMLHttpRequest ? false: true;
  function newtoponload() {
    var c = document.getElementById("full");
    function b() {
      var a = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
      if (a > 0) {
        if (isie6) {
          c.style.display = "none";
          clearTimeout(window.show);
          window.show = setTimeout(function() {
            var d = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
            if (d > 0) {
              c.style.display = "block";
              c.style.top = (400 + d) + "px"
            }
          },
          300)
        } else {
          c.style.display = "block"
        }
      } else {
        c.style.display = "none"
      }
    }
    if (isie6) {
      c.style.position = "absolute"
    }
    window.onscroll = b;
    b()
  }
  if (window.attachEvent) {
    window.attachEvent("onload", newtoponload)
  } else {
    window.addEventListener("load", newtoponload, false)
  }
  document.getElementById("full").onclick = function() {
    window.scrollTo(0, 0)
  };
</script>

 

本站效果截图:

未命名23

| 1 分2 分3 分4 分5 分 (5.00- 4票) Loading ... Loading ... | 归档目录:建站技术, 移动互联, 软件技术 | 标签: , , |

DRBD远程实时双机热备系统配置完全手册

今天本来想按照之前的计划,分析一下drbd的源码,看到/proc/drbd文件的实现方式时,就想打开drbd服务切实看一下,结果发现几年前配置过的drbd已经不能再使用了,还是先把配置过程完整再尝试一下,以便记录在这里分享出来。

首先需要准备两台虚拟机,可以使用vmware或者virtualos。本文主要针对drbd的配置和使用过程,虚拟机安装部分不作详述。

步骤:

(一)安装虚拟机

安装配置Linux OS,目前桌面版的Linux系统都是免费的,可以很容易获取到安装镜像源。常用的有:Ubutun、Fedora和OpenSuse,可以自行选用。

(二)给虚拟机配置网络

最好都能上外网,以便下载安装常用软件包。

(三)安装drbd软件

上述的Linux桌面发行版自带的安装源中都能找到drbd的安装包。如果没有,那么需要自行下载源码编译安装,这样安装过程中一般会出现不少问题,Google或者百度能解决。

这里以我的两个虚拟机为例:
visual_machine_linux 
在做drbd实验之前,需要对虚拟机做快照备份,防止中途OS崩溃无法启动后可以回退。

系统配置:
虚拟机1
[root@t ~]# hostname
t
[root@t ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:0C:29:07:3D:A8
inet addr:192.168.1.104 Bcast:255.255.255.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe07:3da8/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:280652 errors:0 dropped:0 overruns:0 frame:0
TX packets:2326851 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:26215565 (25.0 MiB) TX bytes:3493042943 (3.2 GiB)
Interrupt:19 Base address:0x2024

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

[root@t ~]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
192.168.1.104 localhost.localdomain localhost localhost t
::1 localhost6.localdomain6 localhost6
192.168.1.106 Shentar

192.168.1.104 ME

[root@t ~]#

虚拟机2
[root@Shentar /]# hostname
Shentar
[root@Shentar /]# ifconfig
eth1 Link encap:Ethernet HWaddr 00:0C:29:39:C4:28
inet addr:192.168.1.106 Bcast:255.255.255.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe39:c428/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2327200 errors:0 dropped:0 overruns:0 frame:0
TX packets:280717 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3492827412 (3.2 GiB) TX bytes:26300053 (25.0 MiB)
Interrupt:19 Base address:0x2024

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

[root@Shentar /]# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
192.168.1.106 localhost.localdomain localhost localhost Shentar
::1 localhost6.localdomain6 localhost6
192.168.1.104 t

192.168.1.106 ME

(四)在配置好了虚拟机之后,给每个虚拟机增加一块硬盘,用作drbd的镜像源。

准备供drbd管理的磁盘,对于虚拟机很方便,直接添加硬盘即可。添加步骤:

  1. 打开虚拟机的设置对话框:

    wps_clip_image-26891
  2. 点击add按钮

    wps_clip_image-27328
  3. 一路next即可。
  4. 添加完成后的虚拟机配置如下:

    wps_clip_image-27459 
    启动虚拟机

    使用fdisk -l命令会发现系统中多了一块硬盘设备:

    [root@Shentar ~]# fdisk -l

    Disk /dev/sdc: 3221 MB, 3221225472 bytes
    255 heads, 63 sectors/track, 391 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Disk identifier: 0x00000000

    Disk /dev/sdc doesn't contain a valid partition table

    注:这里的显示内容中已经将其他无关的磁盘信息删除。
  5. 对新加的硬盘创建分区,按照如下步骤执行即可:
    [root@Shentar ~]# fdisk /dev/sdc

    Command (m for help): n
    Command action
    e extended
    p primary partition (1-4)
    p
    Partition number (1-4): 1
    First cylinder (1-391, default 1):
    Using default value 1
    Last cylinder or +size or +sizeM or +sizeK (1-391, default 391):
    Using default value 391

    Command (m for help): w
    The partition table has been altered!

    Calling ioctl() to re-read partition table.
    Syncing disks.
    [root@Shentar ~]# fdisk -l

    Disk /dev/sdc: 3221 MB, 3221225472 bytes
    255 heads, 63 sectors/track, 391 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Disk identifier: 0x2a28d263

    Device Boot Start End Blocks Id System
    /dev/sdc1 1 391 3140676 83 Linux

(五)配置drbd.conf文件

两台虚拟机都配置完毕后,可以配置drbd.conf文件了。我的两台虚拟机的配置文件如下

[root@Shentar ~]# cat /etc/drbd.conf 

#
# please have a a look at the example configuration file in
# /usr/share/doc/packages/drbd.conf
#
resource r0 {
protocol C;

startup {
wfc-timeout 2000;
degr-wfc-timeout 6000;
}

syncer {
rate 50M;
}

disk {
on-io-error pass_on;
}

on Shentar {
device /dev/drbd2;
disk /dev/sdc1;
address 192.168.1.106:7789;
meta-disk internal;
}

on t {
device /dev/drbd2;
disk /dev/sdc1;
address 192.168.1.104:7789;
meta-disk internal;
}
}

两台虚拟机的配置完全一样即可。

 
(六)创建drbd资源

执行如下两条命令创建drbd资源:

[root@Shentar ~]# drbdadm create-md r0

[root@t ~]# drbdadm create-md r0

其中r0是配置文件中指定的资源名。

(七)初次启动drbd

  • 启动两台虚拟机上面的drbd服务。

/etc/init.d/drbd start

先启动的一台虚拟机会等待另外一台,一直停留在如下等待画面:

[root@t ~]# /etc/init.d/drbd start

Starting DRBD resources: [ d(r0) s(r0) n(r0) ]..........
***************************************************************
DRBD's startup script waits for the peer node(s) to appear.
- In case this node was already a degraded cluster before the
reboot the timeout is 6000 seconds. [degr-wfc-timeout]
- If the peer was available before the reboot the timeout will
expire after 2000 seconds. [wfc-timeout]
(These values are for resource '
r0'; 0 sec -> wait forever)
To abort waiting enter '
yes' [ 30]:

等待另一台启动后,会自动完成启动。

  • 查看系统进程,会发现多了3个drbd相关的进程:
[root@t ~]# proc

PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
0 2 0 0 ? -1 S< 0 0:00 [kthreadd]
2 2966 0 0 ? -1 S 0 0:00 \_ [drbd2_worker]
2 2975 0 0 ? -1 S 0 0:00 \_ [drbd2_receiver]
2 3014 0 0 ? -1 S 0 0:00 \_ [drbd2_asender]

我的理解,drbd2_worker为本地磁盘管理内核线程,drbd2_receiver为接受对端同步数据的线程,drbd2_asender为本地发送数据到对端内核线程。

此时,使用drbd内核线程的状态,会发现二者已经建立联系:

[root@t ~]# cat /proc/drbd 

version: 8.3.5 (api:88/proto:86-91)

GIT-hash: ded8cdf09b0efa1460e8ce7a72327c60ff2210fb build by root@t, 2010-05-22 10:36:02

2: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r----

ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:b oos:3140544

检查drbd是否创建了设备drbd2:

[root@t ~]# l /dev/drbd2 

brw-r----- 1 root disk 147, 2 2013-07-14 16:04 /dev/drbd2

[root@t ~]#

说明drbd的磁盘设备已经创建成功了。

/proc/drbd 文件是内核线程写的,当用户态打开该文件时,内核线程会将此时本端监控到的连接状态反馈给用户。PS:从这里可以看出,我的drbd是在2010年编译安装的,这个时间也够久远了。

到这里已经可以确认drbd安装、配置成功了。

但是还需要强制指定一端为主,并在新的drbd设备上面创建文件系统,方能挂载到系统使用。

  • 在其中一个节点执行如下命令,强制置主:

[root@t ~]# drbdsetup /dev/drbd2 primary -o

此时再查看drbd的工作状态,会发现两台主机的drbd之间已经在同步数据了,同步速度为50M/s,这个速度是配置文件中指定的。


[root@t~]#cat/proc/drbd
version:8.3.5(api:88/proto:86-91)
GIT-hash:ded8cdf09b0efa1460e8ce7a72327c60ff2210fbbuildbyroot@t,2010-05-2210:36:02
2:cs:SyncSourcero:Primary/Secondaryds:UpToDate/InconsistentCr----
ns:372792nr:0dw:0dr:380960al:0bm:22lo:1pe:13ua:256ap:0ep:1wo:boos:2768160
[=>..................]sync'ed:12.0%(2768160/3140544)K
finish:0:01:06speed:41,376(41,376)K/sec

不必等待同步完成,已经可以在主端创建文件和使用了,但是在数据同步完成之前不能倒换或者强制重启的动作,否则会出现主备数据不一致的问题,导致“脑裂”出现。

数据同步完成后,状态显示为:


[root@t~]#cat/proc/drbd
version:8.3.5(api:88/proto:86-91)
GIT-hash:ded8cdf09b0efa1460e8ce7a72327c60ff2210fbbuildbyroot@t,2010-05-2210:36:02
2:cs:Connectedro:Primary/Secondaryds:UpToDate/UpToDateCr----
ns:3140544nr:0dw:0dr:3140544al:0bm:192lo:0pe:0ua:0ap:0ep:1wo:boos:0

  • 对drbd虚拟设备做文件系统:

[root@t~]#mkfs.ext3/dev/drbd2
mke2fs1.40.8(13-Mar-2008)
Warning:256-byteinodesnotusableonoldersystems
Filesystemlabel=
OStype:Linux
Blocksize=4096(log=2)
Fragmentsize=4096(log=2)
196608inodes,785136blocks
39256blocks(5.00%)reservedforthesuperuser
Firstdatablock=0
Maximumfilesystemblocks=805306368
24blockgroups
32768blockspergroup,32768fragmentspergroup
8192inodespergroup
Superblockbackupsstoredonblocks:
32768,98304,163840,229376,294912
Writinginodetables:done
Creatingjournal(16384blocks):done
Writingsuperblocksandfilesystemaccountinginformation:done
Thisfilesystemwillbeautomaticallycheckedevery38mountsor
180days,whichevercomesfirst.Usetune2fs-cor-itooverride.

注意,文件系统只在一端做即可,另一端会在数据同步完成后就自动有文件系统了。同样创建的文件的权限也会同步到对端。因此两边操作系统的同名用户的用户id和组id也要完全一样,否则会出现同名用户创建的文件到了对端后出现该用户无法访问的问题。该问题在不指定用户id创建系统用户时比较容易出现,也比较隐藏。

  • 现在就可以挂载使用drbd的虚拟磁盘设备/dev/drbd2 了。

[root@t/]#mkdirdrbd2/
[root@t/]#mount/dev/drbd2/drbd2

无出错提示,则挂载成功。

下面就可以在用户态下使用drbd的分区了。

  • 做一个最简单的试验,在主节点创建一个文件,然后倒换到备,在备上面查看该文件:

[root@t/drbd2]#echo'hellodrbd!'>./justatest.txt
[root@t/drbd2]#catjustatest.txt
hellodrbd!
  • 然后倒换drbd。

在主端执行如下命令:


cd/
umount/drbd2
drbdadmsecondaryall
[root@t/drbd2]#cd/
[root@t/]#umount/drbd2
[root@t/]#drbdadmsecondaryall
[root@t/]#cat/proc/drbd
version:8.3.5(api:88/proto:86-91)
GIT-hash:ded8cdf09b0efa1460e8ce7a72327c60ff2210fbbuildbyroot@t,2010-05-2210:36:02
2:cs:Connectedro:Secondary/Secondaryds:UpToDate/UpToDateCr----
ns:3256620nr:0dw:116076dr:3140673al:41bm:221lo:0pe:0ua:0ap:0ep:1wo:boos:0
[root@t/]#

在备端执行如下命令:


[root@Shentar/drbd2]#drbdadmprimaryall
[root@Shentar/]#mkdir/drbd2
[root@Shentar/]#mount/dev/drbd2/drbd2

然后再查看备端的文件是否同步成功:


[root@Shentar/drbd2]#cd/
[root@Shentar/]#cd/drbd2/
[root@Shentar/drbd2]#catjustatest.txt
hellodrbd!
[root@Shentar/drbd2]#

可以看到备端没有作文件系统,但是可以直接挂载磁盘,并打开主端同步过来的文件。

 (八)后面就可以在drbd上面架数据库或者其他对文件持久化要求比较高的应用了。

Drbd在文件系统下层,直接管理块设备的块,因此如果是上层应用自身将数据结构破坏,那么坏的数据也会被同步到对端。如果是一端磁盘损坏,那么倒换后,也许数据还是好的,可以继续起上层应用,起到容灾的作用。Drbd不会自动倒换,需要在双机控制应用程序中写监控和倒换脚本来控制。

| 1 分2 分3 分4 分5 分 (5.00- 5票) Loading ... Loading ... | 归档目录:DRBD, 软件技术 | 标签: , , |

Netty和Jetty的Java NIO 网络框架模型分析

Netty的NIO框架模型。在以前的文章中,为解决Jetty的问题,分析过Java NIO基于多路事件分离器的异步IO框架模型。一直都没有系统分析Netty和Jetty的网络模型,这两天将二者的网络框架部分的代码仔细读了一下,整理了二者的网络模型,画出了Netty的模型图:

netty_network_frame_model

在图中,每个侦听都会创建一个Acceptor Reactor,由Boss线程来监控多路分离器,这里只关注连接事件,当有新的建立连接请求达到时,该线程会第一时间响应,将接收到的请求注册到事件多路分离器中,事件多路分离器有多个,默认情况下其个数为CPU核心数的两倍,应该是CPU超线程的数目。这里会给每一个达到的连接编一个序号,将序号对分离器个数取模(hash到0~3的一维空间),根据模值分配给相应的分离器。事件分离器开始监听新的连接上面的读写事件。检查线程为NioWorker。读写数据会通过回调用户注册的handler的相应接口来实现。因此,处理耗时数据的情况下,需要用户将其提交给后台线程,而不应该阻塞事件分离器,否则会导致新的连接无法建立,其他并发请求无法处理。

Jetty在代码风格上面跟Netty差别很大,看jetty代码感觉更清晰一点,可能是因为以前处理问题已经看得非常多了。前面的文章也说过,Jetty是在一个线程中调用一个同步的accept()方法来等待新的连接请求,等到新的连接到来时,就生成新的change事件放到多路分离器中,同样也是有多个多路分离器,选取原则与Netty完全一样。简单的轮询实现负载均衡。这是典型的半同步半异步(Half-Sync/Half-Async)的模式。在只使用1个事件分离器时,会发现分发线程通常会引入很多问题。前面两篇文章中提到的问题分析都跟这个有关。

不知道Jetty与Netty为什么在接受新请求这里有差别,难道Netty的方式更利于处理短连接,而Jetty则更利于处理长连接,比如Http连接?优待进一步的并发测试才能说明问题。如果netty的方式很好,那么Jetty应该也早就改成了该方式。

| 1 分2 分3 分4 分5 分 (5.00- 9票) Loading ... Loading ... | 归档目录:IO编程, Jetty, Netty | 标签: , , |

班车即将涨价

diao丝听闻班车涨价,旋即入手白色5系一辆————单车。掐指一算,这得半年才能骑回成本。#生命在于折腾#

DSCF0028

| 1 分2 分3 分4 分5 分 (4.80- 5票) Loading ... Loading ... | 归档目录:生活札记 |

分布式存储知识学习清单(完善中)

分布式存储是云存储和云计算的基石。没有特别深入的存储基础知识,但是对分布式存储比较感兴趣。希望以不同的开源存储系统的架构特点和细节组成一条学习的主线,以点带面的掌握主流的架构、算法和适用场景。

1、DRBD

1)磁盘IO的截获和处理流程;
2)同步和异步IO复制流程
3)内核态与用户态交互流程
4)文件系统、VFS和块IO之间的关系

2、Ceph

1)对象接口
2)分布式存储的元数据与数据节点分离架构

3、VFS

1)内核知识点
2)本地文件系统

4、关系数据库

1)PostgreSQL、Sqlite,SQL语法,DB文件组织的数据结构

5、算法

1)PAXOS算法:Chubby、BigTable、GFS论文
2)NoSQL、Cassandra、Voldemort,节点间消息通讯模型,多副本一致性保障。
3)CAP定理相关

| 1 分2 分3 分4 分5 分 (4.78- 9票) Loading ... Loading ... | 归档目录:C/C++, Java, Linux内核, 算法数据结构 |
返回顶部