当前位置: 首页 > 编程日记 > 正文

Hadoop集群安全性:Hadoop中Namenode单点故障的解决方案及详介AvatarNode

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

正如大家所知,NameNode在Hadoop系统中存在单点故障问题,这个对于标榜高可用性的Hadoop来说一直是个软肋。本文讨论一下为了解决这个问题而存在的几个solution。

1. Secondary NameNode

原理:Secondary NN会定期的从NN中读取editlog,与自己存储的Image进行合并形成新的metadata image

优点:Hadoop较早的版本都自带,配置简单,基本不需要额外资源(可以与datanode共享机器)

缺点:恢复时间慢,会有部分数据丢失

2. Backup NameNode

原理:backup NN实时得到editlog,当NN宕掉后,手动切换到Backup NN;

优点:从hadoop0.21开始提供这种方案,不会有数据的丢失

缺点:因为需要从DataNode中得到Block的location信息,在切换到Backup NN的时候比较慢(依赖于数据量)

3. Avatar NameNode

原理:这是Facebook提供的一种HA方案,将client访问hadoop的editlog放在NFS中,Standby NN能够实时拿到editlog;DataNode需要同时与Active NN和Standby NN report block信息;

08183202_WAbw.jpg

优点:信息不会丢失,恢复快(秒级)

缺点:Facebook基于Hadoop0.2开发的,部署起来稍微麻烦;需要额外的机器资源,NFS成为又一个单点(不过故障率低)

4. Hadoop2.0直接支持StandBy NN,借鉴Facebook的Avatar,然后做了点改进

08183203_YXK7.png

优点:信息不会丢失,恢复快(秒级),部署简单


--------------------------------------------------------------------------------------------------------------------------------------------------------------------


详细介绍Hadoop NameNode单点问题解决方案之一 AvatarNode


需求:

实现namenode元数据的备份,解决namenode单点宕机导致集群不可用的问题。

方案描述:

当namenode所在服务器宕机的时候,我们可以利用namenode备份的元数据迅速重构新的namenode来投入使用。

1.  Hadoop 本身提供了可利用secondarynamenode的备份数据来恢复namenode的元数据的方案,但因为checkpoint(在每次 checkpoint的时候secondarynamenode才会合并并同步namenode的数据)的问题,secondarynamenode的备 份数据并不能时刻保持与namenode同步,也就是说在namenode宕机的时候secondarynamenode可能会丢失一段时间的数据,这段 时间取决于checkpoint的周期。我们可以减小checkpoint的周期来减少数据的丢失量,但由于每次checkpoint很耗性能,而且这种 方案也不能从根本上解决数据丢失的问题。所以如果需求上不允许这种数据的丢失,这种方案可直接不予考虑。

2.  Hadoop 提供的另一种方案就是NFS,一种即时备份namenode元数据的方案,设置多个data目录(包括NFS目录),让namenode在持 久化元数据的时候同时写入多个目录,这种方案较第一种方案的优势是能避免数据的丢失(这里我们暂时不讨论NFS本身会丢失数据的可能性,毕竟这种几率很小 很小)。既然可以解决数据丢失的问题,说明这套方案在原理上是可行的

下载源码


https://github.com/facebook/hadoop-20


部署环境


机器4台


hadoop1-192.168.64.41 AvatarNode(primary)


hadoop2-192.168.64.42 AvataDataNode


hadoop3-192.168.64.43 AvataDataNode


hadoop4- 192.168.64.67 AvatarNode(standby)




相关资源及描述


以下是Avatar方案部署相关的简单介绍。


1.首先关于Avatar方案对于Hadoop的备份是对Dfs的的单点备份,并不包括Mapred,因为Hadoop本身就不存在处理jobtracker单点故障的机制。


2.AvatarNode继承自Namenode,而并非对Namenode的修改,AvatarDataNode同样亦如此。故Avatar的启动机制是独立于Hadoop本身的启动机制。


3.在Avatar方案中,SecondaryNamenode的职责已包括在Standby节点中,故不需要再独立启动一个SecondaryNamenode。


4.AvatarNode必须有NFS的支持,用以实现两个节点间事务日志(editlog)的共享。


5.FB提供的Avatar源码中暂时并不能实现Primary和Standby之间的自动切换,可以借助于Zookeeper的lease机制来实现自动切换。


6.Primary和Standby之间的切换只包括从Standby切换到Primary,并不支持从Primary状态切换到Standby状态。


7.AvatarDataNode并不使用VIP和AvatarNode通信,而是直接与Primary及Standby通信,故需要使用VIP漂移方案来屏蔽两个节点间切换过程中的IP变换问题。有关与Zookeeper的整合,官方称将在之后的版本发布。


关于AvatarNode更详细的介绍,请参考http://blog.csdn.net/rzhzhz/article/details/7235789,


三、编译


1.  首先修改hadoop根目录下build.xml,注释掉996行和1000行。如下:


<targetname="forrest.check"unless="forrest.home"depends="java5.check">

<!--fail message="'forrest.home' is not defined. Pleasepass-Dforrest.home=<base of Apache Forrest installation> to Antonthe command-line." /-->

</target>

<target name="java5.check" unless="java5.home">

<!--fail message="'java5.home' is not defined.  Forrest requires Java 5. Please pass -Djava5.home=<base of Java5 distribution> to Ant onthe command-line." /-->

</target>


2.     在根目录下输入ant jar(对于编译package可以参考build.xml的代码)编译hadoop,编译后的jar包会在build目录下(hadoop- 0.20.3-dev-core.jar), 拷贝该jar包到hadoop根目录下替换到原有的jar (啰嗦一句,hadoop启动时会先加载build目录下的class,所以当通过替换class修改jar包时请先把build目录暂时移除掉) 。


3.  进入src/contrib/highavailability目录下编译Avatar,编译后的jar包 会在build/contrib/highavailability目录下(hadoop-${version}- highavailability.jar),拷贝该jar包到lib目录下。


4.     把2,3步中编译好的jar包分发到集群中所有机器的相应目录。


四、配置


1.     配置hdfs-site.xml


<?xmlversion="1.0"?>


<?xml-stylesheettype="text/xsl"href="configuration.xsl"?>




<!-- Put site-specificproperty overrides in thisfile. -->




<configuration>


<property>


<name>dfs.name.dir</name>


<value>/data/hadoop/hdfs/name</value>


<description>Determineswhereon the local filesystem the DFS name node shouldstore the name table. Ifthis is a  comma-delimited list ofdirectories then the name tableis replicated in all of thedirectories, for redundancy


</description>


</property>


<property>


<name>dfs.data.dir</name>


<value>/data/hadoop/facebook_hadoop_data/hdfs/data</value>


</property>


<property>


<name>dfs.datanode.address</name>


<value>0.0.0.0:50011</value>


<description>默认为50010, 是datanode的监听端口</description>


</property>


<property>


<name>dfs.datanode.http.address</name>


<value>0.0.0.0:50076</value>


<description>默认为50075,为datanode的http server端口</description>


</property>


<property>


<name>dfs.datanode.ipc.address</name>


<value>0.0.0.0:50021</value>


<description>默认为50020, 为datanode的ipc server端口</description>


</property>


<property>


<name>dfs.http.address0</name>


<value>192.168.64.41:50070</value>


</property>


<property>


<name>dfs.http.address1</name>


<value>192.168.64.67:50070 </value>


</property>


<property>


<name>dfs.name.dir.shared0</name>


<value>/data/hadoop/share/shared0</value>


</property>


<property>


<name>dfs.name.dir.shared1</name>


<value>/data/hadoop/share/shared1</value>


</property>


<property>


<name>dfs.name.edits.dir.shared0</name>


<value>/data/hadoop/share/shared0</value>


</property>


<property>


<name>dfs.name.edits.dir.shared1</name>


<value>/data/hadoop/share/shared1</value>


</property>


<property>


<name>dfs.replication</name>


<value>2</value>


<description>


Defaultblock replication. The actual number of replicationscan bespecified when the file is created. The default isused ifreplicationis not specified in create  time


</description>


</property>


</configuration>


参数说明:


1)  dfs.name.dir.shared0


AvatarNode(Primary)元数据存储目录,注意不能和dfs.name.dir目录相同


2)  dfs.name.dir.shared1


AvatarNode(Standby)元数据存储目录,注意不能和dfs.name.dir目录相同


3)  dfs.name.edits.dir.shared0


AvatarNode(Primary) edits文件存储目录,默认与              dfs.name.dir.shared0一致


4)  dfs.name.edits.dir.shared1


AvatarNode(Standby) edits文件存储目录,默认与         dfs.name.dir.shared1一致


5)  dfs.http.address0


AvatarNode(Primary) HTTP的监控地址


6)  dfs.http.address1


AvatarNode(Standby) HTTP的监控地址


7)  dfs.namenode.dn-address0/dfs.namenode.dn-address1


虽然在Avatar源码中有所涉及,但暂时并未用到


2.  配置core-site.xml


<?xmlversion="1.0"?>


<?xml-stylesheettype="text/xsl"href="configuration.xsl"?>




<!-- Putsite-specificproperty overrides in this file. -->




<configuration>


<property>


<name>hadoop.tmp.dir</name>


<value>/home/hadoop/tmp</value>


<description>A baseforother temporary directories.


</description>


</property>


<property>


<name>fs.default.name</name>


<value>hdfs://192.168.64.41:9600</value>


<description>The name ofthedefault file system. Eitherthe                   literal string"local" or a host:port for DFS.


</description>


</property>


<property>


<name>fs.default.name0</name>


<value>hdfs://192.168.64.41:9600</value>


<description>The name ofthedefault file system. Eitherthe                   literal string"local" or a host:port for DFS.


</description>


</property>


<property>


<name>fs.default.name1</name>


<value>hdfs://192.168.64.67:9600</value>


<description>The name ofthedefault file system. Eitherthe                   literal string"local" or a host:port for DFS.


</description>


</property>


</configuration>


参数说明:


1)  fs.default.name


当前AvatarNode IP地址和端口号,即Primary和Standby的配置为各自的IP地址和端口号。


2)  fs.default.name0


AvatarNode(Primary) IP地址和端口号


3)  fs.default.name1


AvatarNode(Standby)  IP地址和端口号


3.     因为不涉及到mapred,故mapred-site.xml不用作修改,为原有集群配置即可。


4.     分发修改后的配置文件到集群节点并在Primary和Standby节点上建立好配置文件中相应目录。


5.     建立NFS,实现Primary与Standby shared0目录的数据共享。有关NFS的配置请参考http://blog.csdn.net/rzhzhz/article/details/7056732


6.     格式化Primary与Standby,这里可以采用hadoop本身的格式化命令,也可以采用AvatarNode的格式化命令 (bin/hadooporg.apache.hadoop.hdfs.AvatarShell -format),但此时shared1目录不能为空,此处有点多余。建议采用hadoop本身的格式化命令在Primary上格式化后,并且把name 目录下的文件复制到shared0目录下。然后再在Standby上复制shared0目录下的文件到shared1目录下。


五、启动


1.     由于不涉及jobtracker的单点,在这里我们只启动hdfs相关线程。Primary,Standby两个namenode(此处Standby包括SecondaryNamenode的职责)和3个AvatarDataNode数据节点。


2.     在Primary节点hadoop根目录下启动AvatarNode(Primary)


bin/hadooporg.apache.hadoop.hdfs.server.namenode.AvatarNode–zero


3.     在Standby节点hadoop根目录下启动AvatarNode(Standby)


bin/hadooporg.apache.hadoop.hdfs.server.namenode.AvatarNode-one–standby


4.     依次在数据节点hadoop根目录下启动AvatarDataNode


bin/hadooporg.apache.hadoop.hdfs.server.datanode.AvatarDataNode


5.     其他相关命令


bin/hadoop   org.apache.hadoop.hdfs.server.namenode.AvatarNode,后面可    选参数有


[-standby] | [-sync] |[-zero] | [-one] | [-format] |  [-upgrade]   | [-rollback] |[-finalize] | [-importCheckpoint]


##查看当前AvatarNode的状态


1)   bin/hadoop org.apache.hadoop.hdfs.AvatarShell –showAvatar


##primary 把当前Standby节点升级Primary节点


2) bin/hadooporg.apache.hadoop.hdfs.AvatarShell  -setAvatar


3)  bin/hadooporg.apache.hadoop.hdfs.AvatarShell -setAvatar standby




集群测试


1.     访问集群的web页


(Primary)http://hadoop1-virtual-machine:50070


(Standby)http://hadoop5-virtual-machine:50070


可见所有的AvatarDataNode都已注册到两个namenode,Primary处于正常状态,而Standby处于Safemode状态,只可读不可写。可通过AvatarShell命令查看当前AvatarNode的状态(Primary或Standby)。


2.     存储相关数据到集群,集群正常工作。


3.     Kill掉Primary节点的AvatartNode线程,在Standby把当前升级为Prirmary,数据并未丢失,集群正常工作(此时 web端不能正常访问文件系统,通过shell命令可查看集群数据)。但由于Avatar有转换限制,只能由Standby转换成Primary,故一次 故障后,由Standby上升为Primary的节点并不能重新降级为Standby,所以不能实现像Master/Slave那种自由切换。


转载于:https://my.oschina.net/u/2377453/blog/464283

相关文章:

PE文件和COFF文件格式分析——RVA和RA相互计算

之前几节一直是理论性质的东西非常多。本文将会讲到利用之前的知识得出一个一个非常有用的一个应用。&#xff08;转载请指明来源于breaksoftware的csdn博客&#xff09; 首先我们说下磁盘上A.exe文件和正在内存中运行的A.xe之间的关系。当我们双击A.exe后&#xff0c;A.exe会运…

《评人工智能如何走向新阶段》后记(再续9)

由AI科技大本营下载自视觉中国2019.12.16 96. 近日《Nature》杂志推荐2019年度10大科学进展的杰出论文&#xff0c;其中一篇是有关人工智能的&#xff0c;谈采用深度学习/强化学习算法来训练四足机器狗ANYmal&#xff0c;使它能快速爬起来。该文谈到&#xff0c;在反复训练下&…

RTX组织架构刷新出现了问题

今天发现RTX的组织架构刷新出现了问题。按照网络上的方法什么的把什么配置文件的IP地址改啊改啊。还是没有用。也TELNET了8010端口&#xff0c;也没有用。其实这样的方法之前把服务程序装在另一台机器上倒是可以的。有点麻烦的了。呵呵不知道各位博友有没有解决的好方法啊。呵呵…

一个最简单的通过WireShark破解SSL加密网络数据包的方法

原文地址&#xff1a; http://article.yeeyan.org/view/530101/444688 一般来说&#xff0c;我们用WireShark来抓取包进行分析是没有多大问题的。但这里有个问题是&#xff0c;如果你碰到的是用SSL/TLS等加密手段加密过的网络数据的时候&#xff0c;往往我们只能束手无策。在过…

PE文件和COFF文件格式分析——导出表

在之前的《PE可选文件头》相关博文中我们介绍了可选文件头中很多重要的属性&#xff0c;而其中一个非常重要的属性是&#xff08;转载请指明来源于breaksoftware的CSDN博客&#xff09; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; 该数组保存了…

将Quartz.NET集成到 Castle中

Castle是针对.NET平台的一个开源项目&#xff0c;从数据访问框架ORM到IOC容器&#xff0c;再到WEB层的MVC框架、AOP&#xff0c;基本包括了整个开发过程中的所有东西&#xff0c;为我们快速的构建企业级的应用程序提供了很好的服务.具体可参看TerryLee的Castle 开发系列文章。 …

《评人工智能如何走向新阶段》后记(再续10)

本文由AI科技大本营下载自视觉中国106.百度自研的飞桨&#xff08;Paddle paddle&#xff09;框架是中国自研的首个开源产业极人工智能深度学习框架&#xff0c;目前飞桨已累计服务150多万开发者&#xff0c;在定制化训练平台上企业用户超过6.5万&#xff0c;发布了16.9万模型&…

水管工游戏 (深搜)

水管工游戏 本题依然是采用搜索&#xff0c;深搜&#xff0c;广搜都可以&#xff0c;本代码采用深搜&#xff0c;此题在搜索时需要增加一些判断条件以及下一步要搜索的位置即可。 代码如下&#xff1a; #include<stdio.h> int a[51][51]; int book[51][51],n,m,flag0,top…

PE文件和COFF文件格式分析——导出表的应用——一种插件模型

可能在很多人想想中&#xff0c;只有DLL才有导出表&#xff0c;而Exe不应该有导出表。而在《PE文件和COFF文件格式分析——导出表》中&#xff0c;我却避开了这个话题。我就是想在本文中讨论下载Exe中存在导出表的场景。&#xff08;转载请指明出于breaksoftware的csdn博客&…

IBatis.Net学习笔记九--动态选择Dao的设计分析

在IBatis.Net中可以通过配置文件动态选择数据库、动态选择Dao对象。Dao对象也就是操作数据库的类&#xff0c;通过配置文件我们可以选择DataMapper的方式、Ado的方式、NHibernet的方式以前其他第三方的方式来操作数据库。有利于系统的灵活性和可扩展性。通过分析动态选择Dao的设…

Pytorch和Tensorflow,谁会笑到最后?

作者 | 土豆变成泥来源 | 知秋路&#xff08;ID:gh_4a538bd95663&#xff09;【导读】作为谷歌tensorflow某项目的Contributor&#xff0c;已经迅速弃坑转向Pytorch。目前Tensorflow还没有被Pytorch比下去&#xff0c;但之后极大概率被比下去。01 在学术界Pytorch已经超越Tenso…

HTTP请求的过程

HTTP通信机制是在一次完整的HTTP通信过程中&#xff0c;Web浏览器与Web服务器之间将完成下列7个步骤&#xff1a; 1. 建立TCP连接在HTTP工作开始之前&#xff0c;Web浏览器首先要通过网络与Web服务器建立连接&#xff0c;该连接是通过TCP来完成的&#xff0c;该协议与IP协议共同…

JSTL+EL表达式方法获取Oracle的Clob字段内容

我们在页面获得数据的时候一般的类型还是很好获得的,但是一遇到Clob类型就比较麻烦,最常用的方法是用一个流将其读取出来.使用MVC框架的时候这些都是无所谓的事情,因为反正是写在java类中怎么写都行,可是不使用MVC框架,使用jsp页面JSTL的sql标签去读取数据库的数据这种方式就麻…

通向人工智能产业落地化的道路在哪?

整理 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;世事浮云&#xff0c;白云苍狗&#xff0c;转眼间关于人工智能的研究已历经两个世纪。在研究者和践行者的不懈努力之下&#xff0c;如今人工智能应用已遍地可见&#xff0c;无论是繁华都市还是偏远小镇&…

PE文件和COFF文件格式分析——导出表的应用——通过导出表隐性加载DLL

通过导出表隐性加载DLL&#xff1f;导出表&#xff1f;加载DLL&#xff1f;还隐性&#xff1f;是的。如果觉得不可思议&#xff0c;可以先看《PE文件和COFF文件格式分析——导出表》中关于“导出地址表”的详细介绍。&#xff08;转载请指明出于breaksoftware的csdn博客&#x…

系统启动时,spring配置文件解析失败,报”cvc-elt.1: 找不到元素 'beans' 的声明“异常...

现象&#xff1a;spring加载配置文件applicationContext.xml出错,抛出nested exception is og.xml.sax.SAXParseException; lineNumber: 12; columnNumber: 47; cvc-elt.1: 找不到元素 beans 的声明r的异常信息。 造成该异常原因有两种&#xff1a;第一,配置文件头部配置的xsd版…

DllMain中不当操作导致死锁问题的分析--死锁介绍

最近在网上看到一些关于在DllMain中不当操作导致死锁的问题&#xff0c;也没找到比较确切的解答&#xff0c;这极大吸引了我研究这个问题的兴趣。我花了一点时间研究了下&#xff0c;正好也趁机研究了下进程对DllMain的调用规律。因为整个研究篇幅比较长&#xff0c;我觉得还是…

XGBoost缺失值引发的问题及其深度分析 | CSDN博文精选

作者 | 兆军&#xff08;美团配送事业部算法平台团队技术专家&#xff09;来源 | 美团技术团队&#xff08;*点击阅读原文&#xff0c;查看美团技术团队更多文章&#xff09;背景XGBoost模型作为机器学习中的一大“杀器”&#xff0c;被广泛应用于数据科学竞赛和工业领域&#…

什么是CPI指数和GDP

即消费者物价指数(Consumer Price Index)&#xff0c;英文缩写为CPI&#xff0c;是反映与居民生活有关的产品及劳务价格统计出来的物价变动指标&#xff0c;通常作为观察通货膨胀水平的重要指标。如果消费者物价指数升幅过大&#xff0c;表明通胀已经成为经济不稳定因素&#x…

The Ultimate Guide To iPhone Resolutions

2019独角兽企业重金招聘Python工程师标准>>> ios 屏幕尺寸 像素 等说明 转载于:https://my.oschina.net/starmier/blog/467271

DllMain中不当操作导致死锁问题的分析--进程对DllMain函数的调用规律的研究和分析

不知道大家是否思考过一个过程&#xff1a;系统试图运行我们写的程序&#xff0c;它是怎么知道程序起始位置的&#xff1f;很多同学想到&#xff0c;我们在编写程序时有个函数&#xff0c;类似Main这样的名字。是的&#xff01;这就是系统给我们提供的控制程序最开始的地方&…

力挺Python!同是程序员,为啥同事年前就实现了财务自由?

人红是非多&#xff0c;最近Python就遇到了这样的问题。与技术社区上一片「形势大好」对比鲜明的是&#xff0c;国内技术圈却一直存在对Python&#xff0c;「力挺」和「吃瓜」两派阵营&#xff0c;针锋相对&#xff0c;那么&#xff0c;Python到底有没有用&#xff0c;真相究竟…

C# 判断远程文件是否存在

#region 判断远程文件是否存在/// <summary>/// 判断远程文件是否存在/// </summary>/// <param name"fileUrl"></param>/// <returns></returns>public static bool RemoteFileExists(string fileUrl){HttpWebRequest re null…

DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子

有了前面两节的基础&#xff0c;我们现在切入正题&#xff1a;研究下DllMain为什么会因为不当操作导致死锁的问题。首先我们看一段比较经典的“DllMain中死锁”代码。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; //主线程中 HMODULE h LoadLibraryA(strD…

性能超FPN!北大、阿里等提多层特征金字塔网络

作者 | Qijie Zhao等编译 | 李杰出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;特征金字塔网络具有处理不同物体尺度变化的能力&#xff0c;因此被广泛应用到one-stage目标检测网络&#xff08;如DSSD&#xff0c;RetinaNet&#xff0c;RefineDet&#xff09;和two-…

什么是WIFI

WIFI全称Wireless Fidelity&#xff0c;又称802.11b标准&#xff0c;它的最大优点就是传输速度较高&#xff0c;可以达到11Mbps&#xff0c;另外它的有效距离也很长&#xff0c;同时也与已有的各种802.11DSSS设备兼容。 WIFI是由AP(Access Point)和无线网卡组成的无线网络。…

Android入门——电话拨号器和4种点击事件

关于HelloWorld为,电话拨号程序还AndroidA入门demo,从这个样例我们要理清楚做安卓项目的思路。大体分为三步&#xff1a; 1.理解需求&#xff0c;理清思路 2.设计UI 3.代码实现 电话拨号器 1. 理解需求&#xff1a; *一个文本框——用来接收电话号码 *一个button——用来触发事…

DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子2

本文介绍使用Windbg去验证《DllMain中不当操作导致死锁问题的分析--导致DllMain中死锁的关键隐藏因子》中的结论&#xff0c;调试对象是文中刚开始那个例子。&#xff08;转载请指明出于breaksoftware的csdn博客&#xff09; 1 g 让程序运行起来 2 ctrlbreak 中断程序 3 ~ 查看…

从入门到深入:移动平台模型裁剪与优化的技术探索与工程实践

可以看到&#xff0c;通过机器学习技术&#xff0c;软件或服务的功能和体验得到了质的提升。比如&#xff0c;我们甚至可以通过启发式引擎智能地预测并调节云计算分布式系统的节点压力&#xff0c;以此改善服务的弹性和稳定性&#xff0c;这是多么美妙。而对移动平台来说&#…

我在不炎熱也不抑鬱的秋天,依然不抽煙

写过几次电影的观后感,挺过瘾.最近看到my little airport的那张新唱片,再也没有办法保持沉默了 为什么人家的唱片名都起的和小说一样,难得是为了证明听歌的人们都不喜欢动笔吗? 于是,我建了个类别,叫 我也会听歌.很明显,这里面会塞一些和歌相关的东西 这是第一篇