posts - 200, comments - 8, trackbacks - 0, articles - 0

     摘要: 转自:http://www.redisbook.com 跳跃表¶跳跃表(skiplist)是一种随机化的数据, 由 William Pugh 在论文《Skip lists: a probabilistic alternative to balanced trees》中提出, 这种数据结构以有序的方式在层次化的链表中保存元素, 它的效率可以和平衡树媲美 ——...  阅读全文

posted @ 2013-04-06 20:45 鑫龙 阅读(2222) | 评论 (0)编辑 收藏

     摘要: 本文内容框架: §1 Skip List 介绍 §2 Skip List 定义以及构造步骤 §3 Skip List 完整实现 §4 Skip List 概率分析 §5 小结   §1 Skip List 介绍  Skip List是一种随机化的数据结构,基于并联的链表,其效率可...  阅读全文

posted @ 2013-04-06 19:55 鑫龙 阅读(13311) | 评论 (0)编辑 收藏

     摘要:  转自:http://www.redisbook.com字典字典(dictionary), 又名映射(map)或关联数组(associative array), 它是一种抽象数据结构, 由一集键值对(key-value pairs)组成, 各个键值对的键各不相同, 程序可以将新的键值对添加到字典中, 或者基于键进行查找、更新或删除等操作。本章先对字典在 Redis 中的应用进行...  阅读全文

posted @ 2013-04-05 19:00 鑫龙 阅读(3874) | 评论 (0)编辑 收藏

     摘要:  转自:http://www.redisbook.com双端链表链表作为数组之外的一种常用序列抽象, 是大多数高级语言的基本数据类型, 因为 C 语言本身不支持链表类型, 大部分 C 程序都会自己实现一种链表类型, Redis 也不例外 —— 它实现了一个双端链表结构。双端链表作为一种常见的数据结构, 在大部分的数据结构或者算法书里都有讲解, 因此, 这一章关注的...  阅读全文

posted @ 2013-04-05 18:05 鑫龙 阅读(494) | 评论 (0)编辑 收藏

     摘要: 转自:http://www.redisbook.com简单动态字符串Sds (Simple Dynamic String,简单动态字符串)是 Redis 底层所使用的字符串表示, 它被用在几乎所有的 Redis 模块中。本章将对 sds 的实现、性能和功能等方面进行介绍, 并说明 Redis 使用 sds 而不是传统 C 字符串的原因。sds 的用途Sds 在 Redis 中的主要作用有以下两个:...  阅读全文

posted @ 2013-04-05 17:54 鑫龙 阅读(1121) | 评论 (0)编辑 收藏

     摘要: 虽然Redis已经很火了,相信还是有很多同学对Redis只是有所听闻或者了解并不全面,下面是一个比较系统的Redis介绍,对Redis的特性及各种数据类型及操作进行了介绍。是一个很不错的Redis入门教程。1.介绍1.1 Redis是什么REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统...  阅读全文

posted @ 2013-04-05 14:46 鑫龙 阅读(494) | 评论 (0)编辑 收藏

     摘要: 目录:1. Linux系统调用原理2. 系统调用的实现3. Linux系统调用分类及列表4.系统调用、用户编程接口(API)、系统命令和内核函数的关系5. Linux系统调用实例6. Linux自定义系统调用1.系统调用原理系统调用,顾名思义,说的是操作系统提供给用户程序调用的一组“特殊”接口。用户程序可以通过这组“特殊”接口来获得操作系统内核提供的...  阅读全文

posted @ 2013-04-04 11:57 鑫龙 阅读(1189) | 评论 (0)编辑 收藏

回环设备(loop-back devices) ¶

回环设备( 'loopback device')允许用户以一个普通磁盘文件虚拟一个块设备。设想一个磁盘设备,对它的所有读写操作都将被重定向到读写一个名为 disk-image 的普通文件而非操作实际磁盘或分区的轨道和扇区。(当然,disk-image 必须存在于一个实际的磁盘上,而这个磁盘必须比虚拟的磁盘容量更大。)回环设备允许你这样使用一个普通文件。

回环设备以 /dev/loop0、/dev/loop1 等命名。每个设备可虚拟一个块设备。注意只有超级用户才有权限设置回环设备。

回环设备的使用与其它任何块设备相同。特别是,你可以在这个设备上创建文件系统并像普通的磁盘一样将它挂载在系统中。这样的一个将全部内容保存在一个普通文件中的文件系统,被称为虚拟文件系统(virtual file system)(译者注:这个用法并不常见。VFS 通常另有所指,如指代 Linux 内核中有关文件系统抽象的代码层次等)。

可以通过下列步骤创建一个虚拟文件系统并通过回环设备挂载:

创建一个用于承载虚拟文件系统的空文件。这个文件的大小将成为挂载后文件系统的大小。
创建指定大小文件的简单方法是通过 dd 命令。这个命令以块为单位(通常为 512 字节)从一个文件向另一个文件复制数据。/dev/zero 文件则是一个很好的数据来源。
要建立一个 10 MB 大的名为 disk-image 的文件可以通过以下命令:
% dd if=/dev/zero of=/tmp/disk-image count=20480
20480+0 records in
20480+0 records out
% ls -l /tmp/disk-image
-rw-rw----     1 root      root       10485760 Mar   8 01:56 /tmp/disk-image
这个新建立的文件被填满了 0 字节。在挂载之前,必须在其上建立一个文件系统。这个过程会建立许多用于组织和存储文件的控制单元并构造根目录结构。
在这个磁盘映像之上可以构建任何类型的文件系统。以创建 ext2 文件系统为例(ext2 是 Linux 系统中最常见的文件系统),用 mke2fs 可以完成这个操作。因为这个命令通常是针对块设备进行操作,当对一个普通文件操作时它会要求确认:
% mke2fs -q /tmp/disk-image
mke2fs 1.18, 11-Nov-1999 for EXT2 FS 0.5b, 95/08/09
disk-image is not a block special device.
Proceed anyway? (y,n) y
这里 -q 参数用于省略输出有关新建立文件系统的概要信息。如果你想看到这些信息,则请省略这个参数。
现在 disk-image 文件包含了一个新建立的文件系统,正如一个被刚刚初始化完毕的 10 MB 大小的磁盘。
以一个环回设备挂载这个文件系统。方法是使用 mount 命令,指定磁盘文件为被挂载的设备。同时指定 loop=loopback-device 作为 -o 选项的参数,告诉 mount 命令使用哪个回环设备。
下面例子中的命令可用于挂载我们的 disk-image 文件系统。要记住的是只有超级用户可以使用环回设备。第一个命令将创建一个目录 /tmp/virtual-fs,这个目录将被用于挂载我们的文件系统。
% mkdir /tmp/virtual-fs
% mount -o loopback=/dev/loop0 /tmp/disk-image /tmp/virtual-fs
这时,这个设备应该已经被挂载,就如同一个普通的 10M 空间的磁盘一样。
% df -h /tmp/virtual-fs
Filesystem   Size Used Avail Use% Mounted on
/tmp/disk-image 9.7M 13k 9.2M 0% /tmp/virtual-fs
你可以向任何其它磁盘一样使用这个设备:
% cd /tmp/virtual-fs
% echo 'Hello, world!' > test.txt
% ls -l
total 19
drwxr-xr-x 2   root root 12288 Mar 8 02:00 lost+found
-rw-rw---- 1   root root     14 Mar 8 02:12 test.txt
% cat test.txt
Hello, world!
请注意 lost+found 是一个由 mke2fs 自动建立的文件夹一旦文件系统被破坏,部分数据被回复但没有与任何文件关联起来,将被放置在这个文件夹中。。
结束使用后,卸载这个文件系统:
% cd /tmp
% umount /tmp/virtual-fs
你可以删除 disk-image,或者之后再次挂载并使用其中的文件。你甚至可以将这个文件复制到远程主机并在那里挂载、使用——文件系统的内容完全不会受到影响。
除了从新创建一个文件系统,还可以从一个现有的文件系统复制而得到一份映像。例如,可以通过普通的复制操作为一个 CD-ROM 创建一份映像。

如果系统中有一个 IDE 接口的 CD-ROM 驱动器,使用前面说过的设备名如 /dev/hda。如果 CD-ROM 是 SCSI 接口的话,设备文件名可能是 /dev/scd0 之类。系统中也可能包含一个符号链接 /dev/cdrom 指向实际的光驱。请参考 /etc/fstab (译者注: 手册)查看系统实际使用的光驱对应的设备。

接下来要做的仅仅是将这个设备复制为一个文件——得到的文件将是被存在硬盘上的、这个 CD-ROM 内容的完整映像。例如:

% cp /dev/cdrom /tmp/cdrom-image
取决于设备的速度和 CD-ROM 的容量,这个操作可能需要几分钟的时间。最终的文件将会相当大,它的体积与这个 CD-ROM 的容量相同。

这时,你可以在系统中挂载这个光盘而无须插入原始的 CD-ROM 盘片。要挂载在 /mnt/cdrom 目录下:

mount -o loopback=/dev/loop0 /tmp/cdrom-image /mnt/cdrom
因为映像位于磁盘上,这个文件系统的速度将远胜于直接挂载自实际光驱的时候。请注意多数光盘使用的文件系统类型都是   iso9660。

posted @ 2013-04-03 19:47 鑫龙 阅读(521) | 评论 (0)编辑 收藏

Redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、 list(链表)、set(集合)和zset(有序集合)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操 作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的 是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。Redis 是一个高性能的key-value数据库。
redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部分场合可以对关系数据库起到很好的补充作用。它提供了Python,Ruby,Erlang,PHP客户端,使用很方便。(以上内容摘自百度百科)

一:下载redis并安装

  1. [root@server11 ~]# wget http://redis.googlecode.com/files/redis-2.6.4.tar.gz  
  2. [root@server11 ~]# tar -zxvpf redis-2.6.4.tar.gz   
  3. [root@server11 ~]# cd redis-2.6.4  
  4. [root@server11 redis-2.6.4]# make install 

32位操作系统上可能会出现如下报错:
zmalloc.o: In function `zmalloc_used_memory':
/root/redis-2.6.4/src/zmalloc.c:223: undefined reference to `__sync_add_and_fetch_4'
collect2: ld returned 1 exit status
make[1]: *** [redis-server] Error 1
make[1]: Leaving directory `/root/redis-2.6.4/src'
make: *** [all] Error 2

解决方案参考:
https://groups.google.com/forum/?fromgroups#!topic/redis-db/NI_d00he39o

二:编辑redis配置文件,启动redis

  1. [root@server11 ~]# mkdir -p /usr/local/redis2/{bin,etc,var}  
  2. [root@server11 redis-2.6.4]# cp redis.conf /usr/local/redis2/etc/  
  3. [root@server11 redis-2.6.4]# cp /usr/local/bin/redis-* /usr/local/redis2/bin/  
  4.  
  5. [root@server11 ~]# grep -v '^#' /usr/local/redis2/etc/redis.conf |grep -v '^$' //各参数含义在配置文件中有具体的解释和介绍  
  6. daemonize yes   
  7. pidfile /usr/local/redis2/var/redis.pid  
  8. port 6379  
  9. bind 192.168.1.112   
  10. timeout 300   
  11. loglevel notice  
  12. logfile stdout  
  13. databases 16  
  14. save 900 1  
  15. save 300 10  
  16. save 60 10000  
  17. stop-writes-on-bgsave-error yes  
  18. rdbcompression yes  
  19. rdbchecksum yes  
  20. dbfilename dump.rdb  
  21. dir ./  
  22. slave-serve-stale-data yes  
  23. slave-read-only yes  
  24. slave-priority 100  
  25. appendonly no  
  26. appendfsync everysec  
  27. no-appendfsync-on-rewrite no  
  28. auto-aof-rewrite-percentage 100  
  29. auto-aof-rewrite-min-size 64mb  
  30. lua-time-limit 5000  
  31. slowlog-log-slower-than 10000  
  32. slowlog-max-len 128  
  33. hash-max-ziplist-entries 512  
  34. hash-max-ziplist-value 64  
  35. list-max-ziplist-entries 512  
  36. list-max-ziplist-value 64  
  37. set-max-intset-entries 512  
  38. zset-max-ziplist-entries 128  
  39. zset-max-ziplist-value 64  
  40. activerehashing yes  
  41. client-output-buffer-limit normal 0 0 0  
  42. client-output-buffer-limit slave 256mb 64mb 60  
  43. client-output-buffer-limit pubsub 32mb 8mb 60  
  44.  
  45. [root@server11 ~]# /usr/local/redis2/bin/redis-server  /usr/local/redis2/etc/redis.conf   
  46. [root@server11 ~]# netstat -ntpl |grep 6379  
  47. tcp        0      0 192.168.1.112:6379          0.0.0.0:*                   LISTEN      6044/redis-server    
  48.  
  49. [root@server11 ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.112  
  50. redis 192.168.1.112:6379> set number 100  
  51. OK  
  52. redis 192.168.1.112:6379> get number  
  53. "100"  
  54. redis 192.168.1.112:6379> del number  
  55. (integer) 1  
  56. redis 192.168.1.112:6379> get number  
  57. (nil)  
  58. redis 192.168.1.112:6379> quit 

三: redis主从配置,关闭主节点的redis实例,复制/usr/local/redis2/目录至从节点

  1. [root@server11 ~]# ps -ef |grep redis  
  2. root      6044     1  0 09:37 ?        00:00:00 /usr/local/redis2/bin/redis-server /usr/local/redis2/etc/redis.conf  
  3. root      6072 27475  0 09:44 pts/1    00:00:00 grep redis  
  4. [root@server11 ~]# kill 6044  
  5. [root@server11 ~]# scp -rvp /usr/local/redis2/ root@192.168.1.113:/usr/local/  
  6.  
  7. [root@server12 ~]# grep -v '^#'  /usr/local/redis2/etc/redis.conf  |grep -v '^$' //注意红色字体部分  
  8. daemonize yes   
  9. pidfile /usr/local/redis2/var/redis.pid  
  10. port 6379  
  11. bind 192.168.1.113  
  12. timeout 300   
  13. loglevel notice  
  14. logfile stdout  
  15. databases 16  
  16. save 900 1  
  17. save 300 10  
  18. save 60 10000  
  19. stop-writes-on-bgsave-error yes  
  20. rdbcompression yes  
  21. rdbchecksum yes  
  22. dbfilename salve.rdb  
  23. dir ./  
  24. slaveof 192.168.1.112 6379 
  25. slave-serve-stale-data yes  
  26. slave-read-only yes  
  27. slave-priority 100  
  28. appendonly no  
  29. appendfsync everysec  
  30. no-appendfsync-on-rewrite no  
  31. auto-aof-rewrite-percentage 100  
  32. auto-aof-rewrite-min-size 64mb  
  33. lua-time-limit 5000  
  34. slowlog-log-slower-than 10000  
  35. slowlog-max-len 128  
  36. hash-max-ziplist-entries 512  
  37. hash-max-ziplist-value 64  
  38. list-max-ziplist-entries 512  
  39. list-max-ziplist-value 64  
  40. set-max-intset-entries 512  
  41. zset-max-ziplist-entries 128  
  42. zset-max-ziplist-value 64  
  43. activerehashing yes  
  44. client-output-buffer-limit normal 0 0 0  
  45. client-output-buffer-limit slave 256mb 64mb 60  
  46. client-output-buffer-limit pubsub 32mb 8mb 60 

四:分别启动主从节点redis实例并测试

  1. [root@server11 ~]# /usr/local/redis2/bin/redis-server /usr/local/redis2/etc/redis.conf   
  2. [root@server12 ~]# /usr/local/redis2/bin/redis-server /usr/local/redis2/etc/redis.conf   
  3.  
  4. [root@server12 ~]# netstat -ntpl |grep 6379  
  5. tcp        0      0 192.168.1.113:6379          0.0.0.0:*                   LISTEN      16653/redis-server    
  6.  
  7. [root@server11 ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.112  
  8. redis 192.168.1.112:6379> set number 1  
  9. OK  
  10. redis 192.168.1.112:6379> get number   
  11. "1"  
  12. redis 192.168.1.112:6379> quit  
  13.  
  14. [root@server11 ~]# /usr/local/redis2/bin/redis-cli -h 192.168.1.113  
  15. redis 192.168.1.113:6379> get number  
  16. "1"  
  17. redis 192.168.1.113:6379> del number  
  18. (error) READONLY You can't write against a read only slave.  
  19. redis 192.168.1.113:6379> quit

posted @ 2013-04-03 18:41 鑫龙 阅读(479) | 评论 (0)编辑 收藏

本文地址:博客园 逖靖寒 http://gpcuster.cnblogs.com

前提

1. 了解JUnit4.x的使用。
2. 了解Mock的概念在单元测试中的应用。
3. 了解Hadoop中MapReduce的编程模型。

    如果您对Junit和Mock不了解,可以先阅读[翻译]Unit testing with JUnit 4.x and EasyMock in Eclipse - Tutorial

    如果您对Hadoop中MapReduce的编程模型不了解,可以先阅读Map/Reduce Tutorial

    介绍

    MRUnit是一款由Couldera公司开发的专门针对Hadoop中编写MapReduce单元测试的框架。

    它可以用于0.18.x版本中的经典org.apache.hadoop.mapred.*的模型,也能在0.20.x版本org.apache.hadoop.mapreduce.*的新模型中使用。

    官方的介绍如下:

    MRUnit is a unit test library designed to facilitate easy integration between your MapReduce development process and standard development and testing tools such as JUnit. MRUnit contains mock objects that behave like classes you interact with during MapReduce execution (e.g., InputSplit and OutputCollector) as well as test harness "drivers" that test your program's correctness while maintaining compliance with the MapReduce semantics. Mapper and Reducer implementations can be tested individually, as well as together to form a full MapReduce job.

    安装

    在目前Hadoop的发行版中,并没有默认包含MRUnit。你需要去Couldera公司的官网中去下载一个由他们再次发行的版本。

    推荐的版本为:hadoop-0.20.1+133.tar.gz

    下载这个文件后,你将在hadoop-0.20.1+133\contrib\mrunit目录中找到我们需要的jar包:hadoop-0.20.1+133-mrunit.jar。

    为了使用MRUnit,我们需要将hadoop-0.20.1+133-mrunit.jar和Junit4.x使用的jar包:junit.jar都添加到我们开发Hadoop程序项目的classpath中。

    示例

    代码是最好的文档,我们先看一个简单的map单元测试示例,代码如下:

    package gpcuster.cnblogs.com;

    import junit.framework.TestCase;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapred.Mapper;
    import org.apache.hadoop.mapred.lib.IdentityMapper;
    import org.junit.Before;
    import org.junit.Test;
    import org.apache.hadoop.mrunit.MapDriver;

    public class TestExample extends TestCase {

    private Mapper<Text, Text, Text, Text> mapper;
    private MapDriver<Text, Text, Text, Text> driver;

    @Before
    public void setUp() {
    mapper = new IdentityMapper<Text, Text>();
    driver = new MapDriver<Text, Text, Text, Text>(mapper);
    }

    @Test
    public void testIdentityMapper() {
    driver.withInput(new Text("foo"), new Text("bar"))
    .withOutput(new Text("foo"), new Text("bar"))
    .runTest();
    }
    }

    在这段示例代码中,我们使用的map是org.apache.hadoop.mapred.lib.IdentityMapper。这是一个非常简单的map函数:输入什么,就输出什么。

    org.apache.hadoop.mrunit.MapDriver是我们从MRUnit框架中导入的一个专门用于测试map的类。

    我们通过withInput指定输入的参数,通过withOutput指定我们期望的输出,然后通过runTest运行我们的测试。

    功能

    1. 测试Map,我们可以使用MapDriver。
    2. 测试Reduce,我们可以使用ReduceDriver。
    3. 测试一个完整的MapReduce,我们可以使用MapReduceDriver。
    4. 测试多个MapReduce组合而成的操作,我们可以使用PipelineMapReduceDriver。

      实现

      MRUnit框架非常精简,其核心的单元测试依赖于JUnit。

      由于我们编写的MapReduce函数中包含有一个OutputCollector的对象,所以MRUnit自己实现了一套Mock对象来控制OutputCollector的操作。

      局限

      通过阅读MRUnit的源代码我们会发现:

      1. 不支持MapReduce框架中的分区和排序操作:从Map输出的值经过shuffle处理后直接就导入Reduce中了。
      2. 不支持Streaming实现的MapReduce操作。

        虽然MRUnit有这些局限,但是足以完成大多数的需求。

        参考资料

        http://www.cloudera.com/hadoop-mrunit

         

        本文地址:博客园 逖靖寒 http://gpcuster.cnblogs.com

        posted @ 2013-04-03 11:27 鑫龙 阅读(240) | 评论 (0)编辑 收藏

        仅列出标题
        共20页: 1 2 3 4 5 6 7 8 9 Last