Net – 夏清然的日志 https://www.qingran.net Xia Qingran Geek Blog Sun, 07 Aug 2016 09:50:33 +0000 en-US hourly 1 https://wordpress.org/?v=4.6.1 112893047 [转载]2010年互联网使用统计 https://www.qingran.net/2011/02/%e8%bd%ac%e8%bd%bd2010%e5%b9%b4%e4%ba%92%e8%81%94%e7%bd%91%e4%bd%bf%e7%94%a8%e7%bb%9f%e8%ae%a1/ https://www.qingran.net/2011/02/%e8%bd%ac%e8%bd%bd2010%e5%b9%b4%e4%ba%92%e8%81%94%e7%bd%91%e4%bd%bf%e7%94%a8%e7%bb%9f%e8%ae%a1/#respond Fri, 04 Feb 2011 13:51:59 +0000 https://www.qingran.net/?p=881 2010年互联网使用统计。记录备案。

原文见:http://www.focus.com/images/view/48564/

中文版翻译来自:http://www.ifanr.com/32311

电子邮件概况:

  • 19 亿:全球使用 email 的用户总数
  • 2940 亿:平均每天发出的邮件数量
  • 107 万亿:2010 年全年发出的邮件数量
  • 目前全球有 29 亿个已知的 email 账户,其中 25% 为企业账户。
  • 据估计,2010 年全部邮件中,近 89% 属于垃圾邮件。

垃圾邮件统计:

左边两幅分别是根据地区统计的全球互联网用户(分布)以及垃圾邮件情况,其中,标签色块从上至下依次代表的是:亚洲、欧洲、北美、拉丁美洲/加勒比、非洲、中东、大洋洲/澳大利亚。

全世界网站概况:

  • 截止至 2010 年 12 月,互联网上有 2.55 亿个站点。全年新增站点 2140 万个。
  • 截止至 2010 年末,互联网域名数量为 1.09 亿个,较 09 年增长 7%。
  • 网络服务器市场份额:由于不断有新站点创建,去年一年中,网络服务器市场一直在增长。Apache 以 60% 的市场份额占据第一,遥遥领先第二名微软的 22%。谷歌则排在第四,为6%。Lighttpd 服务器尽管只有最少的 0.5%,但全年用户数量增长 55.7%,增速超过业内其它竞争对象。

互联网用户数在增长:

  • 20 亿:全球范围内互联网用户数总和
  • 14%:2010 年新增用户比例
  • 浏览器份额:IE 仍以 47% 比例占据第一,之后依次是火狐(31%),谷歌 Chrome (15%),Safari (5%)和 Opera(2%)。

社交媒体:

  • 2000 万:每天在 Facebook 上安装的程序数。
  • 70%:美国以外地区的 Facebook 用户数。
  • 2010年末,Facebook 约有 6 亿用户;当年新增用户数 2.5 亿。
  • 1 亿:去年新增 Twitter 账户数。
  • 1.52 亿:互联网上预估的博客数量。
  • 250 亿:2010 年的发推数。

网络媒体流量:

     

  • 20 亿:每天 Youtube 上被观看的视频数量。
  • 每分钟上传到 Youtube 的视频播放时长总和为 35 小时。

84% 的美国网民收看在线视频。已经有 14% 的人曾经上传过视频。

更多的照片:

  • 3 千:每分钟上传到 Flickr 的照片数。
  • 50 亿:截止到去年 9 月,上传到 Flickr 的照片数。
  • 360 亿:每年上传到 Facebook 的照片数。

图片来源:Focus

]]>
https://www.qingran.net/2011/02/%e8%bd%ac%e8%bd%bd2010%e5%b9%b4%e4%ba%92%e8%81%94%e7%bd%91%e4%bd%bf%e7%94%a8%e7%bb%9f%e8%ae%a1/feed/ 0 881
Nginx bigpicture https://www.qingran.net/2010/09/nginx-bigpicture/ https://www.qingran.net/2010/09/nginx-bigpicture/#respond Fri, 17 Sep 2010 13:34:33 +0000 https://www.qingran.net/?p=629 在网上看到的一个哥们绘制的nginx bigpicture,收藏一下

]]>
https://www.qingran.net/2010/09/nginx-bigpicture/feed/ 0 629
Apache2 KeepAlive详解 + subversion优化 https://www.qingran.net/2010/07/apache2-keepalive%e8%af%a6%e8%a7%a3/ https://www.qingran.net/2010/07/apache2-keepalive%e8%af%a6%e8%a7%a3/#comments Thu, 08 Jul 2010 17:23:03 +0000 https://www.qingran.net/?p=502 由于现在subversion的数据有10GB之多,并且一次checkout会有10w个文件之多,所以这两天看如何优化一下我们的subversion,其中一个点就是apache2的keep alive参数。

Apache Keep-Alive扩展源自自HTTP/1.0和HTTP/1.1标准的的持久链接特性。提供了相对长效的HTTP链接方式,用以在同一个TCP连接中进行多次HTTP请求。KeepAlive设置出现在Apache 1.2版本以后。

对于HTTP/1.0的客户端来说,仅当客户端指定使用的时候才会使用持久链接连接。此外,仅当能够预先知道传输的内容长度时,才会与HTTP/1.0的客户端建立持久链接连接。而对于HTTP/1.1的客户端来说,如果没有进行特殊指定,持久将是默认的连接方式。如果客户端进行了请求,将使用数据分块以解决在持久链接里发送未知长度内容的问题。

KeepAliveTimeout的设置说明:
Apache在关闭持久连接前等待下一个请求的秒数。一旦收到一个请求,超时值将会被设置为Timeout指令指定的秒数。
对于高负荷服务器来说,KeepAliveTimeout值较大会导致一些性能方面的问题:超时值越大,与空闲客户端保持连接的进程就越多。

MaxKeepAliveRequests的设置说明:
MaxKeepAliveRequests指令限制了当启用KeepAlive时,每个连接允许的请求数量。如果将此值设为”0″,将不限制请求的数目。我们建议最好将此值设为一个比较大的值,以确保最优的服务器性能。

通过Apache的设置说明,我们明白在对于一个包含许多图片、css、js的静态内容网页, 客户端会在瞬间发出多个HTTP请求,此时多次建立TCP连接会大大降低响应速度且耗费服务器端资源。 此时通过持续连接,可以允许用户在一个TCP连接中发出多个HTTP请求, 减少TCP连接建立次数,提高响应速度。我们可以通过access log统计出连续HTTP请求出现的次数、间隔时间、访问量, 以确定 MaxKeepAliveRequests 和 KeepAliveTimeout 的值。 KeepAliveTimeout 太小发挥不了持续连接的作用;太大了,该断开连接迟迟的在等待,不仅浪费TCP连接数,而且系统中的apache2的进程数目会因此不断增加,使得系统负载升高。

哪么什么决定着我们是不是要开启KeepAlive的因素就很简单了:就是用户一个页面请求中是否会引发向同一个apache2服务器发出多个HTTP的请求。

但是当你的服务器只是在处理动态网页请求时,由于用户很少会瞬间请求多个动态网页(一般都是打开页面之后阅读好半天才点下一页),此时打开KeepAlive无异于浪费TCP连接数。所以此时应该把KeepAlive off之。

而对于提供静态文件服务,例如图片或静态文件服务,如果一用户需要同时从这个服务上得到数个甚至数十个文件,那么KeepAlive不仅仅能减少TCP的链接请求,更能节省apache2的进程资源。
而对于subversion,由于是一个HTTP同步一个文件,所以特别需要KeepAlive的支持,以下是我的配置:

KeepAlive on
KeepAliveTimeout 5
MaxKeepAliveRequests 0
MaxRequestsPerChild 1000
]]>
https://www.qingran.net/2010/07/apache2-keepalive%e8%af%a6%e8%a7%a3/feed/ 2 502
建立Debian APT mirror https://www.qingran.net/2010/06/%e5%bb%ba%e7%ab%8bdebian-apt-mirror/ https://www.qingran.net/2010/06/%e5%bb%ba%e7%ab%8bdebian-apt-mirror/#comments Wed, 30 Jun 2010 08:48:37 +0000 https://www.qingran.net/?p=444 最近在公司内网给开发组内的兄弟建Xen虚拟机,guest装的都是debian lenny,所以就在内网做了一个apt mirror,笔记如下。

0,安装apt-mirror

apt-get install apt-mirror

1,修改/etc/apt/mirror.list为以下内容

# 同时发起的wget数,根据自己网络调整
set nthreads 20

set _tilde 0

deb http://mirrors.163.com/debian stable contrib main non-free

deb-src http://mirrors.163.com/debian stable contrib main non-free

clean http://ftp.us.debian.org/debian

2, 下载源,这个进行了1整夜。

apt-mirror

3,修改web server配置,指向下载的目录 ,以nginx的配置为例:

location ^~ /debian {

root /var/spool/apt-mirror/mirror/mirrors.163.com/;

autoindex on;

}

然后重启nginx

4,修改使用此mirror的debian /etc/apt/sources.llist 文件

deb http://mirrors.163.com/debian stable contrib main non-free

deb-src  http://mirrors.163.com/debian stable contrib main non-free

5,同步apt

apt-get update

开始使用吧。

]]>
https://www.qingran.net/2010/06/%e5%bb%ba%e7%ab%8bdebian-apt-mirror/feed/ 2 444
修正Windows XP 在处理大量网络链接时报 “No Buffer Space Available” https://www.qingran.net/2010/06/%e4%bf%ae%e6%ad%a3windows-xp-%e5%9c%a8%e5%a4%84%e7%90%86%e5%a4%a7%e9%87%8f%e7%bd%91%e7%bb%9c%e9%93%be%e6%8e%a5%e6%97%b6%e6%8a%a5-no-buffer-space-available/ https://www.qingran.net/2010/06/%e4%bf%ae%e6%ad%a3windows-xp-%e5%9c%a8%e5%a4%84%e7%90%86%e5%a4%a7%e9%87%8f%e7%bd%91%e7%bb%9c%e9%93%be%e6%8e%a5%e6%97%b6%e6%8a%a5-no-buffer-space-available/#respond Fri, 18 Jun 2010 06:06:35 +0000 https://www.qingran.net/?p=423 windows XP下在处理大量并发网络链接的时候会经常出现“No Buffer Space Available“的报错,

修改注册表

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

加入DWORD名为TcpNumConnections的键,值为400。

]]>
https://www.qingran.net/2010/06/%e4%bf%ae%e6%ad%a3windows-xp-%e5%9c%a8%e5%a4%84%e7%90%86%e5%a4%a7%e9%87%8f%e7%bd%91%e7%bb%9c%e9%93%be%e6%8e%a5%e6%97%b6%e6%8a%a5-no-buffer-space-available/feed/ 0 423
linode内存大升级 https://www.qingran.net/2010/06/linode%e5%86%85%e5%ad%98%e5%a4%a7%e5%8d%87%e7%ba%a7/ https://www.qingran.net/2010/06/linode%e5%86%85%e5%ad%98%e5%a4%a7%e5%8d%87%e7%ba%a7/#respond Fri, 18 Jun 2010 05:23:27 +0000 https://www.qingran.net/?p=421 刚刚看到的linode blog,linode为了庆祝其7年以来取得的成绩特对旗下所有的VPS进行了42%的内存升级:

http://blog.linode.com/2010/06/16/linode-turns-7-big-ram-increase/

当然需要重启vps之后才能看到。

]]>
https://www.qingran.net/2010/06/linode%e5%86%85%e5%ad%98%e5%a4%a7%e5%8d%87%e7%ba%a7/feed/ 0 421
Hadoop HDFS特性简介 https://www.qingran.net/2010/05/hadoop-hdfs%e7%89%b9%e6%80%a7%e7%ae%80%e4%bb%8b/ https://www.qingran.net/2010/05/hadoop-hdfs%e7%89%b9%e6%80%a7%e7%ae%80%e4%bb%8b/#comments Wed, 19 May 2010 16:15:55 +0000 https://www.qingran.net/?p=335 一个大型项目的10亿以上,单个大小在20KB左右的小文件存储,并且是一次写入多次读取。所以今天着重考察了Hadoop的HDFS分布式文件系统解决方案。

主要参考Hadoop设计文档:http://hadoop.apache.org/common/docs/r0.17.0/hdfs_design.html

Yahoo!的Hadoop使用介绍:http://developer.yahoo.net/blogs/hadoop/2010/05/scalability_of_the_hadoop_dist.html

一、设计思想
1、硬件失效是“常态事件“,而非“偶然事件”。HDFS可能是有上千的机器组成(文档中描述的Yahoo!一个Hadoop集群有4096个节点),任何一个组件都有可能一直失效,因此数据的健壮性错误检测和快速、自动的恢复是HDFS的核心架构目标。

2、 流式数据访问。运行在HDFS上的应用和普通的应用不同,需要流式访问它们的数据集。HDFS的设计中更多的考虑到了数据批处理,而不是用户交互处理。比之数据访问的低延迟问题,更关键的在于数据并发访问的高吞吐量。POSIX标准设置的很多硬性约束对HDFS应用系统不是必需的。为了提高数据的吞吐量,在一些关键方面对 POSIX的语义做了一些修改。

3、 HDFS应用对文件要求的是write-one-read-many访问模型。一个文件经过创建、写,关闭之后就不需要改变。这一假设简化了数据一致性问题,使高吞吐量的数据访问成为可能。典型的如MapReduce框架,或者一个web crawler应用都很适合这个模型。

4、移动计算的代价比之移动数据的代价低。一个应用请求的计算,离它操作的数据越近就越高效,这在数据达到海量级别的时候更是如此。将计算移动到数据附近,比之将数据移动到应用所在显然更好,HDFS提供给应用这样的接口。

5、在异构的软硬件平台间的可移植性。

二、Namenode和Datanode的划分
一个HDFS集群有一个Namenode和一定数目的Datanode组成。
如图:

Namenode是一个中心服务器,负责管理文件系统的namespace和客户端对文件的访问。
Datanode在集群中会有多个,一般是一个节点存在一个,负责管理其自身节点上它们附带的存储。在内部,一个大文件其分成一个或多个block,这些block存储在Datanode集合里。Namenode执行文件系统的namespace相关操作,例如打开、关闭、重命名文件和目录,同时决定了block到具体Datanode节点的映射。Datanode在Namenode的指挥下进行block的创建、删除和复制。
单一节点的Namenode大大简化了系统的架构。Namenode负责保管和管理所有的HDFS元数据,因而在请求Namenode得到文件的位置后就不需要通过Namenode参与而直接从Datanode进行。
为了提高Namenode的性能,所有文件的namespace数据都在内存中维护,所以就天生存在了由于内存大小的限制导致一个HDFS集群的提供服务的文件数量的上限。
根据目前的文档,一个元数据(一个HDFS文件块儿)占用200Bytes,如果是页面抓取的小文件,那么32GB内存能承载1.5亿左右的文件存储(有待精确详细测试)。

三、文件系统操作和namespace的关系
HDFS支持传统的层次型文件组织,与大多数其他文件系统类似,用户可以创建目录,并在其间创建、删除、移动和重命名文件。HDFS不支持user quotas和访问权限,也不支持链接(link),不过当前的架构并不排除实现这些特性。Namenode维护文件系统的namespace,任何对文件系统namespace和文件属性的修改都将被Namenode记录下来。应用可以设置HDFS保存的文件的副本数目,文件副本的数目称为文件的 replication因子,这个信息也是由Namenode保存。

四、数据复制
HDFS被设计成在一个大集群中可以跨机器地可靠地存储海量的文件。它将每个文件存储成block序列,除了最后一个block,所有的block都是同样的大小。文件的所有block为了容错都会被复制。每个文件的block大小和replication因子都是可配置的。Replication因子可以在文件创建的时候配置,以后也可以改变。HDFS中的文件是write-one,并且严格要求在任何时候只有一个writer。Namenode全权管理block的复制,它周期性地从集群中的每个Datanode接收心跳包和一个Blockreport。心跳包的接收表示该Datanode节点正常工作,而Blockreport包括了该Datanode上所有的block组成的列表。

1、副本的存放,副本的存放是HDFS可靠性和性能的关键。庞大的HDFS实例一般运行在多个机架的计算机形成的集群上,不同机架间的两台机器的通讯需要通过交换机,显然通常情况下,同一个机架内的两个节点间的带宽会比不同机架间的两台机器的带宽大。

在大多数情况下,replication因子是3,HDFS的存放策略是将一个副本存放在本地机架上的节点,一个副本放在同一机架上的另一个节点,最后一个副本放在不同机架上的一个节点。机架的错误远远比节点的错误少,这个策略不会影响到数据的可靠性和有效性。三分之一的副本在一个节点上,三分之二在一个机架上,其他保存在剩下的机架中,这一策略改进了写的性能。

2、副本的选择,为了降低整体的带宽消耗和读延时,HDFS会尽量让reader读最近的副本。如果在reader的同一个机架上有一个副本,那么就读该副本。如果一个HDFS集群跨越多个数据中心,那么reader也将首先尝试读本地数据中心的副本。

3、SafeMode
Namenode启动后会进入一个称为SafeMode的特殊状态,处在这个状态的Namenode是不会进行数据块的复制的。Namenode从所有的 Datanode接收心跳包和Blockreport。Blockreport包括了某个Datanode所有的数据块列表。每个block都有指定的最小数目的副本。当Namenode检测确认某个Datanode的数据块副本的最小数目,那么该Datanode就会被认为是安全的;如果一定百分比(这个参数可配置)的数据块检测确认是安全的,那么Namenode将退出SafeMode状态,接下来它会确定还有哪些数据块的副本没有达到指定数目,并将这些block复制到其他Datanode。

五、文件系统元数据的持久化
Namenode存储HDFS的元数据。对于任何对文件元数据产生修改的操作,Namenode都使用一个称为Editlog的事务日志记录下来。例如,在HDFS中创建一个文件,Namenode就会在Editlog中插入一条记录来表示;同样,修改文件的replication因子也将往 Editlog插入一条记录。Namenode在本地OS的文件系统中存储这个Editlog。整个文件系统的namespace,包括block到文件的映射、文件的属性,都存储在称为FsImage的文件中,这个文件也是放在Namenode所在系统的文件系统上。
Namenode在内存中保存着整个文件系统namespace和文件Blockmap的映像。这个关键的元数据设计得很紧凑,一般为200Bytes的内存占用,因而一个带有4G内存的 Namenode足够支撑海量的文件和目录。当Namenode启动时,它从硬盘中读取Editlog和FsImage,将所有Editlog中的事务作用(apply)在内存中的FsImage ,并将这个新版本的FsImage从内存中flush到硬盘上,然后再truncate这个旧的Editlog,因为这个旧的Editlog的事务都已经作用在FsImage上了。这个过程称为checkpoint。在当前实现中,checkpoint只发生在Namenode启动时,在不久的将来我们将实现支持周期性的checkpoint。
Datanode并不知道关于文件的任何东西,除了将文件中的数据保存在本地的文件系统上。它把每个HDFS数据块存储在本地文件系统上隔离的文件中。 Datanode并不在同一个目录创建所有的文件,相反,它用启发式地方法来确定每个目录的最佳文件数目,并且在适当的时候创建子目录。在同一个目录创建所有的文件不是最优的选择,因为本地文件系统可能无法高效地在单一目录中支持大量的文件。当一个Datanode启动时,它扫描本地文件系统,对这些本地文件产生相应的一个所有HDFS数据块的列表,然后发送报告到Namenode,这个报告就是Blockreport。
六、通讯协议
所有的HDFS通讯协议都是构建在TCP/IP协议上。客户端通过一个可配置的端口连接到Namenode,通过ClientProtocol与 Namenode交互。而Datanode是使用DatanodeProtocol与Namenode交互。从ClientProtocol和 Datanodeprotocol抽象出一个远程调用(RPC),在设计上,Namenode不会主动发起RPC,而是是响应来自客户端和 Datanode 的RPC请求。
七、健壮性
HDFS的主要目标就是实现在失败情况下的数据存储可靠性。常见的三种失败:Namenode failures, Datanode failures和网络分割(network partitions)。
1、硬盘数据错误、心跳检测和重新复制
每个Datanode节点都向Namenode周期性地发送心跳包。网络切割可能导致一部分Datanode跟Namenode失去联系。 Namenode通过心跳包的缺失检测到这一情况,并将这些Datanode标记为dead,不会将新的IO请求发给它们。寄存在dead Datanode上的任何数据将不再有效。Datanode的死亡可能引起一些block的副本数目低于指定值,Namenode不断地跟踪需要复制的 block,在任何需要的情况下启动复制。在下列情况可能需要重新复制:某个Datanode节点失效,某个副本遭到损坏,Datanode上的硬盘错误,或者文件的replication因子增大。

2、集群均衡
HDFS支持数据的均衡计划,如果某个Datanode节点上的空闲空间低于特定的临界点,那么就会启动一个计划自动地将数据从一个Datanode搬移到空闲的Datanode。当对某个文件的请求突然增加,那么也可能启动一个计划创建该文件新的副本,并分布到集群中以满足应用的要求。这些均衡计划目前还没有实现。

3、数据完整性
从某个Datanode获取的数据块有可能是损坏的,这个损坏可能是由于Datanode的存储设备错误、网络错误或者软件bug造成的。HDFS客户端软件实现了HDFS文件内容的校验和。当某个客户端创建一个新的HDFS文件,会计算这个文件每个block的校验和,并作为一个单独的隐藏文件保存这些校验和在同一个HDFS namespace下。当客户端检索文件内容,它会确认从Datanode获取的数据跟相应的校验和文件中的校验和是否匹配,如果不匹配,客户端可以选择从其他Datanode获取该block的副本。

4、元数据磁盘错误
FsImage和Editlog是HDFS的核心数据结构。这些文件如果损坏了,整个HDFS实例都将失效。因而,Namenode可以配置成支持维护多个FsImage和Editlog的拷贝。任何对FsImage或者Editlog的修改,都将同步到它们的副本上。这个同步操作可能会降低 Namenode每秒能支持处理的namespace事务。这个代价是可以接受的,因为HDFS是数据密集的,而非元数据密集。当Namenode重启的时候,它总是选取最近的一致的FsImage和Editlog使用。
Namenode在HDFS是单点存在,如果Namenode所在的机器错误,手工的干预是必须的。目前,在另一台机器上重启因故障而停止服务的Namenode这个功能还没实现。

八、数据组织
1、数据块
兼容HDFS的应用都是处理大数据集合的。这些应用都是写数据一次,读却是一次到多次,并且读的速度要满足流式读。HDFS支持文件的write-once,read-many。一个典型的block大小是64MB,因而,文件总是按照64M切分成chunk,每个chunk存储于不同的Datanode上。

2、数据产生步骤
某个客户端创建文件的请求其实并没有立即发给Namenode,事实上,HDFS客户端会将文件数据缓存到本地的一个临时文件。应用的写被透明地重定向到这个临时文件。当这个临时文件累积的数据超过一个block的大小(默认64M),客户端才会联系Namenode。Namenode将文件名插入文件系统的层次结构中,并且分配一个数据块给它,然后返回Datanode的标识符和目标数据块给客户端。客户端将本地临时文件flush到指定的 Datanode上。当文件关闭时,在临时文件中剩余的没有flush的数据也会传输到指定的Datanode,然后客户端告诉Namenode文件已经关闭。此时Namenode才将文件创建操作提交到持久存储。如果Namenode在文件关闭前挂了,该文件将丢失。
上述方法是对通过对HDFS上运行的目标应用认真考虑的结果。如果不采用客户端缓存,由于网络速度和网络堵塞会对吞估量造成比较大的影响。

3、数据块儿复制
当某个客户端向HDFS文件写数据的时候,一开始是写入本地临时文件,假设该文件的replication因子设置为3,那么客户端会从Namenode 获取一张Datanode列表来存放副本。然后客户端开始向第一个Datanode传输数据,第一个Datanode一小部分一小部分(4kb)地接收数据,将每个部分写入本地仓库,并且同时传输该部分到第二个Datanode节点。第二个Datanode也是这样,边收边传,一小部分一小部分地收,存储在本地仓库,同时传给第三个Datanode,第三个Datanode就仅仅是接收并存储了。这就是流水线式的复制。

九、访问接口
HDFS给应用提供了多种访问方式,可以通过DFSShell通过命令行与HDFS数据进行交互,可以通过java API调用,也可以通过C语言的封装API访问,并且提供了浏览器访问的方式。正在开发通过WebDav协议访问的方式。具体使用参考文档。

十、空间的回收
1、文件的删除和恢复
用户或者应用删除某个文件,这个文件并没有立刻从HDFS中删除。相反,HDFS将这个文件mv到/trash目录。当文件还在/trash目录时,该文件可以被迅速地恢复。文件在/trash中保存的时间是可配置的,当超过这个时间,Namenode就会将/trash文件批量从namespace中删除。文件的删除,也将释放关联该文件的数据块。并且需要注意的是,在文件被用户删除和HDFS空闲空间的增加之间会有一个等待时间延迟。
当被删除的文件还保留在/trash目录中的时候,如果用户想恢复这个文件,可以检索浏览/trash目录并检索该文件。/trash目录仅仅保存被删除文件的最近一次拷贝。/trash目录与其他文件目录没有什么不同,除了一点:HDFS在该目录上应用了一个特殊的策略来自动删除文件,目前的默认策略是删除保留超过6小时的文件,这个策略以后会定义成可配置的接口。

2、Replication因子的减小
当某个文件的replication因子减小,Namenode会选择要删除的过剩的副本。下次心跳检测就将该信息传递给Datanode, Datanode就会移除相应的block并释放空间,同样,在调用setReplication方法和集群中的空闲空间增加之间会有一个时间延迟。

参考资料:

Hadoop hdfs design
http://hadoop.apache.org/common/docs/current/hdfs_design.html

hadoop ubuntu installation
http://www.michael-noll.com/wiki/Running_Hadoop_On_Ubuntu_Linux_(Single-Node_Cluster)
http://www.michael-noll.com/wiki/Running_Hadoop_On_Ubuntu_Linux_(Multi-Node_Cluster)

Hadoop and Distributed Computing at Yahoo!
http://developer.yahoo.net/blogs/hadoop/

http://www.blogjava.net/killme2008/archive/2008/06/05/206043.html

]]>
https://www.qingran.net/2010/05/hadoop-hdfs%e7%89%b9%e6%80%a7%e7%ae%80%e4%bb%8b/feed/ 2 335
FreeBSD下安装IPSec VPN https://www.qingran.net/2010/05/freebsd%e4%b8%8b%e5%ae%89%e8%a3%85ipsec-vpn/ https://www.qingran.net/2010/05/freebsd%e4%b8%8b%e5%ae%89%e8%a3%85ipsec-vpn/#comments Fri, 14 May 2010 13:51:41 +0000 https://www.qingran.net/?p=317 本文详细说明在FreeBSD下如何建立IPSec VPN链路。在GNU/Linux下安装IPSec VPN,详见这里

1,  kernel update
2,  ports update

# portsnap fetch extract update

3, kernel configure

# cp /usr/src/sys/i386/conf/GENERIC /usr/src/sys/i386/conf/kernel_ipsec
# cat >> /usr/src/sys/i386/conf/kernel_ipsec << _EOF_
options  IPSEC
options  IPSEC_ESP
device   gif
_EOF_

# cd /usr/src
# make buildkernel KERNCONF=kernel_ipsec
# make installkernel KERNCONF=kernel_ipsec

4,  Edit tunnel – /etc/rc.conf
host 1:

gif_interfaces="gif0"
gifconfig_gif0="A.B.C.D W.X.Y.Z"
ifconfig_gif0="inet 192.168.1.1 192.168.2.1 netmask 0xffffffff"
static_routes="vpn"
route_vpn="192.168.2.0 192.168.2.1 netmask 0xffffff00"

host 2:

gif_interfaces="gif0"
gifconfig_gif0="W.X.Y.Z A.B.C.D"
ifconfig_gif0="inet 192.168.2.1 192.168.1.1 netmask 0xffffffff"
static_routes="vpn"
route_vpn="192.168.1.0 192.168.1.1 netmask 0xffffff00"

5, do tunnel commands
host 1:

# ifconfig gif0 create
# ifconfig gif0 tunnel A.B.C.D W.X.Y.Z
# ifconfig gif0 inet 192.168.1.1 192.168.2.1 netmask 0xffffffff

host 2:

# ifconfig gif0 create
# ifconfig gif0 tunnel W.X.Y.Z A.B.C.D
# ifconfig gif0 inet 192.168.2.1 192.168.1.1 netmask 0xffffffff

6, enable ipsec – /etc/rc.conf

ipsec_enable="YES"
ipsec_file="/etc/ipsec.conf"

7, setkey – /etc/ipsec.conf
host 1:

spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P out ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require;
spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P in ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require;

host 2:

spdadd W.X.Y.Z/32 A.B.C.D/32 ipencap -P out ipsec esp/tunnel/W.X.Y.Z-A.B.C.D/require;
spdadd A.B.C.D/32 W.X.Y.Z/32 ipencap -P in ipsec esp/tunnel/A.B.C.D-W.X.Y.Z/require;

8, enable racoon in /etc/rc.conf

racoon_enable="YES"

9,  racoon configure

# mkdir -p /usr/local/etc/racoon
# echo "A.B.C.D password" > /usr/local/etc/racoon/psk.txt
# chmod 0600 /usr/local/etc/racoon/psk.txt
# cat >> /usr/local/etc/racoon/racoon.conf << _EOF_
path pre_shared_key "/usr/local/etc/racoon/psk.txt";

remote anonymous
{
exchange_mode main,aggressive,base;
proposal {
encryption_algorithm 3des;
hash_algorithm sha1;
authentication_method pre_shared_key ;
dh_group 2 ;
}
}
sainfo anonymous
{
pfs_group 2;
lifetime time 12 hour ;
encryption_algorithm 3des, cast128, blowfish 448, des, rijndael ;
authentication_algorithm hmac_sha1, hmac_md5 ;
compression_algorithm deflate ;
}
_EOF_

10, add route

/sbin/route add -net 10.55.0/16 192.168.1.101
/sbin/route add -net 172.16.0/16 192.168.1.101
/sbin/route add -net 10.69.0/16 192.168.1.101

11, /etc/sysctl.conf

# echo 'net.inet.ip.forwarding=1' >> /etc/sysctl.conf
# sysctl net.inet.ip.forwarding=1

11, ipsec boot

# setkey -F
# setkey -FP
# setkey -f /etc/ipsec.conf
# /usr/local/etc/rc.d/racoon start

12, Done!

]]>
https://www.qingran.net/2010/05/freebsd%e4%b8%8b%e5%ae%89%e8%a3%85ipsec-vpn/feed/ 2 317
GNU/Linux 安装IPSec VPN https://www.qingran.net/2010/05/gnulinu%e5%ae%89%e8%a3%85ipsec-vpn/ https://www.qingran.net/2010/05/gnulinu%e5%ae%89%e8%a3%85ipsec-vpn/#comments Thu, 06 May 2010 08:14:15 +0000 https://www.qingran.net/?p=307 在前面的一篇日志中详细说明了如何建立基于pptpd的VPN,由于pptpd脆弱的安全性和较低的性能,本文介绍一下IPSec VPN的架设。

一下的内容以ubuntu/debian发行版为例。

1,安装 IPSec。IPSec 会对 IP 数据包进行加密和验证。这意味着你的电脑 / 移动设备与服务器之间传输的数据无法被解密、也不能被伪造。我推荐用 openswan 这个后台软件包来跑 IPSec。

用以下命令安装 openswan:

sudo aptitude install openswan

2,用文字编辑器打开 /etc/ipsec.conf,改成这样:

version 2.0
config setup
    nat_traversal=yes
    virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
    oe=off
    protostack=netkey

conn L2TP-PSK-NAT
    rightsubnet=vhost:%priv
    also=L2TP-PSK-noNAT

conn L2TP-PSK-noNAT
    authby=secret
    pfs=no
    auto=add
    keyingtries=3
    rekey=no
    ikelifetime=8h
    keylife=1h
    type=transport
    left=YOUR.SERVER.IP.ADDRESS
    leftprotoport=17/1701
    right=%any
    rightprotoport=17/%any

3,修改 /etc/ipsec.secrets:

YOUR.SERVER.IP.ADDRESS   %any:  PSK "YourSharedSecret"

把“YOUR.SERVER.IP.ADDRESS”,这部分换成你的服务器的 IP 地址,把“YourSharedSecret”

4、运行以下命令:

for each in /proc/sys/net/ipv4/conf/*
do
    echo 0 > $each/accept_redirects
    echo 0 > $each/send_redirects
done

5,检查一下 IPSec 能否正常工作:

sudo ipsec verify

如果在结果中看到「Opportunistic Encryption Support」被禁用了,没关系,其他项 OK 即可。

6,重启 openswan:

sudo /etc/init.d/ipsec restart

7,安装 L2TP。常用的 L2TP 后台软件包是 xl2tpd,它和 openswan 是同一帮人写的。

运行以下命令:

sudo aptitude install xl2tpd

8,用文字编辑器打开 /etc/xl2tpd/xl2tpd.conf,改成这样:

[global]
ipsec saref = yes

[lns default]
ip range = 10.1.2.2-10.1.2.255
local ip = 10.1.2.1
;require chap = yes
refuse chap = yes
refuse pap = yes
require authentication = yes
ppp debug = yes
pppoptfile = /etc/ppp/options.xl2tpd
length bit = yes

这里要注意的是 ip range 一项里的 IP 地址不能和你正在用的 IP 地址重合,也不可与网络上的其他 IP 地址冲突。

9,安装 ppp。这是用来管理 VPN 用户的。

sudo aptitude install ppp

10,检查一下 /etc/ppp 目录里有没有 options.xl2tpd 这个文件,没有的话就建一个,文件内容如下:

require-mschap-v2
ms-dns 208.67.222.222
ms-dns 208.67.220.220
asyncmap 0
auth
crtscts
lock
hide-password
modem
debug
name l2tpd
proxyarp
lcp-echo-interval 30
lcp-echo-failure 4

注意 ms-dns 两行我填的是 OpenDNS。如果你想用其他的 DNS 服务器(例如谷歌的公共 DNS),请自行更换。

11,现在可以添加一个 VPN 用户了。用文字编辑器打开 /etc/ppp/chap-secrets:

# user      server      password            ip
test        l2tpd       testpassword        *

如果你之前设置过 PPTP VPN,chap-secrets 文件里可能已经有了其他用户的列表。你只要把 test l2tpd testpassword * 这样加到后面即可。

12,重启 xl2tpd:

sudo /etc/init.d/xl2tpd restart

13,设置 iptables 的数据包转发:

iptables --table nat --append POSTROUTING --jump MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

14,因为某种原因,openswan 在服务器重启后无法正常自动,所以我们可以在 /etc/rc.local 文件里写入如下语句:

iptables --table nat --append POSTROUTING --jump MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward
for each in /proc/sys/net/ipv4/conf/*
do
    echo 0 > $each/accept_redirects
    echo 0 > $each/send_redirects
done
/etc/init.d/ipsec restart

到这里,设置工作已经基本完成。你可以用 iPhone 或 iPad 试着连一下。记得在「Secret」中填入你在上述第三步里填的 YourSharedSecret。

如果连接成功,上网也没问题的话,恭喜你,大功告成。如果连不上,恐怕还得多做一步。

Ubuntu 9.10 自带的 openswan 版本是 2.6.22, Debian Lenny 带的版本是 2.4.12。这两个版本的 openswan 都有问题。我们的测试结果表明,2.6.24 版的 openswan 可以在上述两版的 Linux 操作系统下正常工作。所以如果做完以上十四步还是连不上的话,请考虑从源码编译 openswan 2.6.24 :

sudo aptitude install libgmp3-dev gawk flex bison
wget http://www.openswan.org/download/openswan-2.6.24.tar.gz
tar xf openswan-2.6.24.tar.gz
cd openswan-2.6.24
make programs
sudo make install

编译需要一段时间。你的 Linux 内核版本需要高于 2.6.6。

然后可以删除原先通过 aptitude 安装的 openswan,并重启之:

sudo aptitude remove openswan
sudo /etc/init.d/ipsec restart
]]>
https://www.qingran.net/2010/05/gnulinu%e5%ae%89%e8%a3%85ipsec-vpn/feed/ 3 307
GNU/Linux使用LVS在多核、多CPU下网卡中断分配调优 https://www.qingran.net/2010/05/gnulinux%e4%bd%bf%e7%94%a8lvs%e5%9c%a8%e5%a4%9a%e6%a0%b8%e3%80%81%e5%a4%9acpu%e4%b8%8b%e7%bd%91%e5%8d%a1%e4%b8%ad%e6%96%ad%e5%88%86%e9%85%8d%e8%b0%83%e4%bc%98/ https://www.qingran.net/2010/05/gnulinux%e4%bd%bf%e7%94%a8lvs%e5%9c%a8%e5%a4%9a%e6%a0%b8%e3%80%81%e5%a4%9acpu%e4%b8%8b%e7%bd%91%e5%8d%a1%e4%b8%ad%e6%96%ad%e5%88%86%e9%85%8d%e8%b0%83%e4%bc%98/#comments Tue, 04 May 2010 09:53:15 +0000 https://www.qingran.net/?p=410 最近一个哥们在做LVS做load balance测试时发现在并发达到1w以后网卡中断只占用了一个CPU,最终导致此CPU的100%,性能再无法提升。

逐步尝试以下方法:

  1. 修改内核参数irqbalance。印象中此参数能把网卡中断平分到多个CPU上。但是查询最新文档发现此参数在最新的内核中已经不存在;
  2. 使用设备中断的smp_affinity:
    • 首先先从/proc/interrupts里查到网卡的中断号,eth0或者bg0所在行的第一列;
    • 修改/proc/irq/<中断编号>/ 下修改 smp_affinity 文件内容。这个文件是一个位掩码,01意味着只有第一个CPU能处理中断,0F意味着四个CPU都会参与处理中断。
    • 但是经过测试发现此方法能把网卡中断绑定到指定的CPU上,但是不能在多个CPU间平均分配。
  3. 使用user space态下的irqbalance daemon,未得到反馈,估计无效;
  4. 使用Intel高端网卡82575,见文档详细说明:
]]>
https://www.qingran.net/2010/05/gnulinux%e4%bd%bf%e7%94%a8lvs%e5%9c%a8%e5%a4%9a%e6%a0%b8%e3%80%81%e5%a4%9acpu%e4%b8%8b%e7%bd%91%e5%8d%a1%e4%b8%ad%e6%96%ad%e5%88%86%e9%85%8d%e8%b0%83%e4%bc%98/feed/ 1 410
DLNA协议简析 https://www.qingran.net/2010/04/dlna%e5%8d%8f%e8%ae%ae%e7%ae%80%e6%9e%90/ https://www.qingran.net/2010/04/dlna%e5%8d%8f%e8%ae%ae%e7%ae%80%e6%9e%90/#comments Tue, 13 Apr 2010 06:18:00 +0000 https://www.qingran.net/?p=266 刚刚看了一下PS3的规格说明书,看到了其支持dlna协议,不明所以,于是google。

DLNA的全称是DIGITAL LIVING NETWORK ALLIANCE,其宗旨是Enjoy your music, photos and videos, anywhere anytime。DLNA(Digital Living Network Alliance) 由索尼、英特尔、微软等发起成立、旨在解决个人PC,消费电器,移动设备在内的无线网络和有线网络的互联互通,使得数字媒体和内容服务的无限制的共享和增长成为可能,目前成员公司已达280多家。DLNA并不是创造技术,而是形成一种解决的方案,一种大家可以遵守的规范。所以,其选择的各种技术和协议都是目前所应用很广泛的技术和协议。

DLNA将其整个应用规定成5个功能组件:

网络互联

  • 有线网络:802.3.i/u
  • 无线网络:802.11/a/b/g

网络协议:

  • 目前支持ipv4
  • 未来支持ipv6

媒体传输:

  • 其规定了所有DLNA设备都必须支持使用HTTP协议进行媒体的传输

设备的发现:

  • 控制和媒体的管理,很多是采用uPnP的UPnP Device Architecture 1.0和UPnP AV 1.0 and UPnP Printer来进行

媒体格式:

  • 图片 JPEG PNG, GIF, TIFF
  • 声音 LPCM AAC, AC-3, ATRAC 3plus, MP3, WMA9
  • 视频 MPEG2 MPEG-1, MPEG-4*, AVC, WMV9

支持dlna的设备:

  • Sony PS3
  • Sony带有Lan接口的Bravia电视

支持dlna的软件:

参考自wikipedia http://en.wikipedia.org/wiki/Digital_Living_Network_Alliance

参考 http://www.rbgrn.net/content/21-how-to-choose-dlna-media-server-windows-mac-os-x-or-linux

]]>
https://www.qingran.net/2010/04/dlna%e5%8d%8f%e8%ae%ae%e7%ae%80%e6%9e%90/feed/ 2 266
米国的网速惊人,有图有真相! https://www.qingran.net/2010/03/%e7%b1%b3%e5%9b%bd%e7%9a%84%e7%bd%91%e9%80%9f%e6%83%8a%e4%ba%ba%ef%bc%8c%e6%9c%89%e5%9b%be%e6%9c%89%e7%9c%9f%e7%9b%b8%ef%bc%81/ https://www.qingran.net/2010/03/%e7%b1%b3%e5%9b%bd%e7%9a%84%e7%bd%91%e9%80%9f%e6%83%8a%e4%ba%ba%ef%bc%8c%e6%9c%89%e5%9b%be%e6%9c%89%e7%9c%9f%e7%9b%b8%ef%bc%81/#respond Fri, 26 Mar 2010 11:14:19 +0000 https://www.qingran.net/?p=209 刚刚从我在位于Dallas的linode VPS下载一个ubuntu-10.04 beta1的ISO,速度惊人,下载一个700MB的文件只需要2分钟多一点:

]]>
https://www.qingran.net/2010/03/%e7%b1%b3%e5%9b%bd%e7%9a%84%e7%bd%91%e9%80%9f%e6%83%8a%e4%ba%ba%ef%bc%8c%e6%9c%89%e5%9b%be%e6%9c%89%e7%9c%9f%e7%9b%b8%ef%bc%81/feed/ 0 209
scp快速回拷文件 https://www.qingran.net/2010/03/scp%e5%bf%ab%e9%80%9f%e5%9b%9e%e6%8b%b7%e6%96%87%e4%bb%b6/ https://www.qingran.net/2010/03/scp%e5%bf%ab%e9%80%9f%e5%9b%9e%e6%8b%b7%e6%96%87%e4%bb%b6/#respond Fri, 26 Mar 2010 06:32:45 +0000 https://www.qingran.net/?p=188 scp快速回拷文件给登录的源主机: scp filename ${SSH_CONNECTION%% *}:~ ]]> https://www.qingran.net/2010/03/scp%e5%bf%ab%e9%80%9f%e5%9b%9e%e6%8b%b7%e6%96%87%e4%bb%b6/feed/ 0 188 W3C Web Architecture big picture https://www.qingran.net/2010/03/w3c-web-architecture-big-picture/ https://www.qingran.net/2010/03/w3c-web-architecture-big-picture/#comments Fri, 12 Mar 2010 03:46:10 +0000 https://www.qingran.net/?p=179 W3C Web Architecture big picture :

来自w3c的slide:How fast does the Web Change?

http://www.w3.org/2008/Talks/0910how-fast/

]]>
https://www.qingran.net/2010/03/w3c-web-architecture-big-picture/feed/ 1 179
GNU/Linux使用pptpd建立VPN网络 https://www.qingran.net/2010/02/gnulinux%e4%bd%bf%e7%94%a8pptpd%e5%bb%ba%e7%ab%8bvpn%e7%bd%91%e7%bb%9c/ https://www.qingran.net/2010/02/gnulinux%e4%bd%bf%e7%94%a8pptpd%e5%bb%ba%e7%ab%8bvpn%e7%bd%91%e7%bb%9c/#comments Mon, 22 Feb 2010 10:11:26 +0000 https://www.qingran.net/?p=123 刚刚做好,留档保存。

VPN方案以前比较熟悉的OpenVPN,不过win下需要单装客户端,所以这次就用pptpd来做,比OpenVPN简单不少。

安装pptpd

以debian/ubuntu为例

# apt-get install pptpd
# apt-get install iptables

配置pptpd

修改/etc/pptpd.conf

localip 10.0.0.1
remoteip 10.0.0.10-250

修改/etc/ppp/pptpd-options

ms-dns <your dns0>
ms-dns <your dns1>

修改密码文件 /etc/ppp/chap-secrets

第一列为用户名,第二列为/etc/ppp/pptpd-options中的name字段(默认为pptpd),第三列为密码,最后一列为允许ip(所有都允许是*)。

iptables转发:

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

sysctl打开ip_forward

sysctl net.ipv4.ip_forward=1

客户端连接:

直接在windows下建立vpn连接,走默认的即可。

完成。

]]>
https://www.qingran.net/2010/02/gnulinux%e4%bd%bf%e7%94%a8pptpd%e5%bb%ba%e7%ab%8bvpn%e7%bd%91%e7%bb%9c/feed/ 1 123
django model加入cache https://www.qingran.net/2009/06/django-model%e5%8a%a0%e5%85%a5cache/ https://www.qingran.net/2009/06/django-model%e5%8a%a0%e5%85%a5cache/#respond Fri, 12 Jun 2009 08:09:14 +0000 https://www.qingran.net/?p=117 近来用django开发不少,对其自带自带的”django.middleware.cache.UpdateCacheMiddleware” 和”django.middleware.cache.FetchFromCacheMiddleware”感觉很不爽,原因有两个:
0,cache的过期控制只能通过超时时间进行,而不能主动通知;
1,全页面的cache粒度太粗。

遂想到django统一的models抽象应该很方便对db的cache进行统一处理,所以就有以下的想法:

目前设计的cache存储的数据结构是按db的行进行cache,cache采用memcached作为存储方式,其数据结构是:

{pointer_key -> model_key}, {model_key -> model}。

point_key:以get方法查询的表名和查询参数为基础构建,例如:’user-{‘username’:’qingran}’或者 ‘user-{‘id’:1}’;
model_key:以数据库的表名和表的primary key为基础构建,例如:’user-1’,’user-2’;
model:就是models class的内容了,在db中就是符合primary key的数据行。

这样的结构能使不同的get参数只要是查询同一个表的同一个行,那么就对应同一个model数据。

cache的命中和过期:
在get的方法,现查{point_key -> model_key},然后查询{model_key -> model}最终得到数据。如果有一步命中失败,就从db取,然后回写cache。
在models进行save和delete方法的时候把{model_key -> model}的对应删除。

但是这样的存储结构目前只能缓存models.Model.objects的get方法请求。而无法对filter方法进行cache。filter cache的难点在于这个查询的结果是一个集合,而集合中的任何一个元素的修改或者新添加一个符合filter查询的数据,都会导致cache失效。

所以说解决filter查询的cache需要解决以下问题:

0,save()和delete()方法中发生时能够快速获知filter的cache是否需要立即更新。
可能”需要手动维护所有filter相关缓存的一个key清单,当你有相关数据发生变动时手动清理相关key。”
另外新增加的符合filter查询要求的元素也会引起cache的失效。

1,因为一个filter查询集合内一个元素的失效就清理整个filter集合可能会cache的更新过于频繁。

啰嗦了一堆,上代码:
===========================================
from django.core.cache import cache
from django.db import models
from django.conf import settings

DOMAIN_CACHE_PREFIX = settings.CACHE_MIDDLEWARE_KEY_PREFIX
CACHE_EXPIRE = settings.CACHE_MIDDLEWARE_SECONDS

def cache_key(model, id):
return (“%s-%s-%s” % (DOMAIN_CACHE_PREFIX, model._meta.db_table,
id)).replace(” “, “”)

class GetCacheManager(models.Manager):
# to reload the get method. cache -> db -> cache
def get(self, *args, **kwargs):
id = repr(kwargs)

# in mc, data are stored in {pointer_key -> model_key},{model_key -> model}
# pointer_key is object.get’s method parameters.
# pointer_key = ‘www-user-{‘username’:’qingran}’ or ‘www-user-{‘id’:1}’
pointer_key = cache_key(self.model, id)

# model_key is “<prefix>-<db tablename>-pk”
# model_key = ‘www-user-1’
model_key = cache.get(pointer_key)

if model_key != None:
model = cache.get(model_key)
if model != None:
return model

# cache MISS, get from db.
model = super(GetCacheManager, self).get(*args, **kwargs)

# write data back to cache from db.
if not model_key:
model_key = cache_key(model, model.pk)
cache.set(pointer_key, model_key, CACHE_EXPIRE)

cache.set(model_key, model, CACHE_EXPIRE)

return model

class ModelWithGetCache(models.Model):
# to reload the save method
def save(self, *args, **kwargs):
# first, delete cache {model_key -> model}
model_key = cache_key(self, self.pk)
cache.delete(model_key)

super(ModelWithGetCache, self).save()

# to reload the delete method
def delete(self, *args, **kwargs):
# first, delete cache {model_key -> model}
model_key = cache_key(self, self.pk)
cache.delete(model_key)

super(ModelWithGetCache, self).delete()

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

在使用的时候定义models需要改从ModelWithGetCache继承,并且指定objects = GetCacheManager()

Sample:
class User(ModelWithGetCache):
objects = GetCacheManager()

]]>
https://www.qingran.net/2009/06/django-model%e5%8a%a0%e5%85%a5cache/feed/ 0 117
Debian/Ubuntu 安装subversion服务 https://www.qingran.net/2009/05/debianubuntu-%e5%ae%89%e8%a3%85subversion%e6%9c%8d%e5%8a%a1/ https://www.qingran.net/2009/05/debianubuntu-%e5%ae%89%e8%a3%85subversion%e6%9c%8d%e5%8a%a1/#respond Sat, 30 May 2009 08:47:01 +0000 https://www.qingran.net/?p=413 笔记一下。

升级apt源

apt-get update

安装SVN

apt-get install subversion subversion-tools apache2 libapache2-svn

创建文件夹

mkdir -p /home/subversion/

subversion初始化目录

svnadmin create /home/subversion/game/

配置Apache方便subversion通过HTTP访问

  1. 安装非SSL加密的HTTP访问
  • 修改/etc/apache2/mods-available/dav_svn.conf 文件
  • 修改权限
    chown -R www-data:www-data /home/subversion/game/
  • 设定apache2

<Location /code>
DAV svn
#SVNParentPath /home/svn
SVNPath /data/svn/code
ModMimeUsePathInfo on
AuthzSVNAccessFile /data/svn/code/conf/authz
AuthzSVNAnonymous off
AuthzSVNNoAuthWhenAnonymousAllowed off
AuthType Basic
AuthName “Subversion”
AuthUserFile /etc/apache2/dav_svn.passwd
Require valid-user
</Location>

  • 设定svn用户组和目录权限,位于以上设置的AuthzSVNAccessFile 路径 /data/svn/code/conf/authz文件内:

[aliases]
# joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average

[groups]
admin = qingran,w
dev = r,a,b,c

[/]
@admin = rw
@dev = rw

 

  • 设置密码
    htpasswd -c /etc/apache2/dav_svn.passwd <username>
    htpasswd /etc/apache2/dav_svn.passwd <username>
]]>
https://www.qingran.net/2009/05/debianubuntu-%e5%ae%89%e8%a3%85subversion%e6%9c%8d%e5%8a%a1/feed/ 0 413
nginx X-Accel-Redirect实现文件下载权限控制 https://www.qingran.net/2009/05/nginx-x-accel-redirect%e5%ae%9e%e7%8e%b0%e6%96%87%e4%bb%b6%e4%b8%8b%e8%bd%bd%e6%9d%83%e9%99%90%e6%8e%a7%e5%88%b6/ Tue, 12 May 2009 07:50:23 +0000 https://www.qingran.net/?p=112 对文件下载的权限进行精确控制在很多地方都需要,例如有偿的下载服务、网络硬盘、个人相册、防止本站内容被外站盗链等。

已知的一些方法有以下几种:

0,通过webserver的rewrite来经常改变下载文件的URL;

1,对HTTP请求的referer头进行判断,要求其必须来自指定的URL;

2,由cgi程序来做权限检查,然后open文件,返回给client;

3,就是本文所说的使用nginx X-Accel-Redirect方法了(lightty也有对应的X-sendfile来完成相同的功能)。

方法0的问题是URL经常变化,且为了防止URL被猜到,要经常的插入一些随机的长字符,造成URL冗长,非常不优雅;方法1是不可靠的,因为 Referer头是由client发出的,完全可以伪造;方法2,因为是由cgi程序打开并读取文件,所以在下载过程中需要持续占用一个cgi进程(线程),并且由于cgi的脚本语言IO速度一般比较慢,导致其总体效率低下。

方法3是我目前认为比较 优雅 的方式 全面 解决此问题的方法。

整个的过程如下图所示:


解释一下整个过程:

步骤0,client请求http://downloaddomain.com/download/my.iso,此请求被CGI程序解析(对于 nginx应该是fastcgi)。

步骤1,CGI程序根据访问者的身份和所请求的资源其是否有下载权限来判定是否有打开的权限。如果有,那么根据此请求得到对应文件的磁盘存放路径,例如是 /var/data/my.iso。那么程序返回时在HTTP header加入X-Accel-Redirect: /protectfile/data/my.iso,并加上head Content-Type:application/octet-stream。

步骤2,nginx得到cgi程序的回应后发现带有X-Accel-Redirect的header,那么根据这个头记录的路径信息打开磁盘文件。

步骤3,nginx把打开文件的内容返回给client端。

这样所有的权限检查都可以在步骤1内完成,而且cgi返回带X-Accel-Redirect的头后,其执行已经终止,剩下的传输文件的工作由nginx 来接管,同时X-Accel-Redirect头的信息被nginx删除,也隐藏了文件实际存储目录,并且由于nginx在打开静态文件上使用了 sendfile(2),其IO效率非常高。

具体如何来做?很简单!

在nginx中的相应的虚拟主机中加入:

location ^~ /protectfile/ {
internal;
alias /var/download/;
add_header Cache-Control no-cache, no-store;
}

然后在cgi程序中加入content-type和x-accel-redirect头,以django为例:

def handle_download(request, filename):

# do some policy control check

… …

response = HttpResponse()

response[‘Content-Type’] = “application/octet-stream”

response[‘X-Accel-Redirect’] = <filepath of the filename>
return response

Done.

]]>
112