[翻译]有关cassandra的存储引擎

Cassandra使用一个类似于日志结构的结合树(Log-Structured Merge Tree)的存储结构,不像传统关系数据库那样使用B-Tree。 Cassandra会避免在写之前去读。 “写前读”(Read-before-write), 特别是在一个大的分布式系统里,会对读性能产生影响,还会带来其它问题,比如,两个客户端同时去读,其中一个去更新该行的A列,另外一个去更新该行的B列,就可能把对A列的更新覆盖掉。“写前读”,也会破坏cache,增加IO。 为了避免“写前读”的情况,cassandra的存储引擎会对即将要进行的插入、更新进行整理,只会按顺序,以追加的模式仅写入这一行更新的部分。 。 一个日志模式的存储引擎,为了避免数据相互覆盖,使用顺序IO去更新数据写入普通硬盘HDD或者固态硬盘SSD是必须的。 在HDD中,随机写比顺序写会导致大量的寻址操作,这个寻址操作的危害是相当大的。使用顺序IO,从而避免更多写入被放大和磁盘故障,Cassandra特别适合廉价的、大众消费的SSD。

2016年5月2日 · 1 分钟

[翻译]Cassandra的写过程

Cassandra的写操作包含几个过程。从开始实时写日志到最后进行压缩。 1、把数据写入commit log 2、数据写入内存表memtable 3、从memtable中刷新 4、存储到磁盘中的sstables里 5、压缩 写日志和memtable存储 当有一个写入发生,cassandra会把数据存到内存里叫memtable的数据结构里,也会写到磁盘的commitlog里,提供持久化存储。commitlog接受每个请求,并且持久化保存,甚至是断电。memtable是一种回写cache,cassandra通过key可以在memtbale里查询数据。memtable的大小是有限制的,当到达一个限制就会被刷新。 从memtable刷新数据。 当memtable的内存超过了配置的阈值,memtable里的数据包括索引,就会进入一个刷新到磁盘的队列里。你可以通过修改cassandra.yaml里的 memtable_heap_space_in_mb配置项来控制这个队列的大小。当要刷新的数据超过了队列大小,cassandra就会阻止写入直到下一个刷新成功。你可以使用nodetool flush 手动触发一个刷新,通常在重启节点之前,建议刷新一次memtable,这样可以减少重放commitlog的时间。为了刷新数据cassandra会吧memetables根据token排序,然后顺序写到磁盘上。 磁盘上数据存储到sstables中 对于在commitlog里的数据,当在memtable里的对应的数据被刷新到一个sstable中之后会被清除。 Memtables和SStables都是分表存储的,SStables是不可以改变的,当从memtbale中刷新到磁盘上后就不会再写入。因此一个分区可以通常会保存到多个sstable文件中。对于每个sstable,cassandra会创建如下结构化数据: 1、分区key索引:一个分区key的列表和对应的在data文件中的起始位置。 2、分区key汇总(在内存里):一个分区key索引的抽样 3、布隆过滤器 压缩 周期性的压缩是cassandra作为一个健康数据库所必须的,因为cassandra不会把数据插入或者更新到具体的位置。当插入或者更新发生了,并不会去覆盖原来的数据,而是重新写入一个新的时间戳版本的数据到另外一个sstable中。cassandra管理在磁盘上不断累积的sstable,就是使用压缩。 cassandra也不会去实际删除数据,因为sstable是不可以修改的。而是用墓碑的方式标记数据被删除了,墓碑存在一个可配置的周期,是表的一个参数 gc_grace_seconds。 在压缩的过程中,会有一个磁盘使用空间以及IO的临时飙升,因为老的和新的sstable会并存,这个图描述了压缩的过程: 压缩会根据分区key合并多个sstable中的数据,选择具有最新时间戳的进行存储。Cassandra可以高性能的合并数据,而不会产生随机IO,因为在sstable里的row都是根据分区key排序存储的。在删除了墓碑和要删除的数据,列和行数据后,压缩的过程会把这些sstable压缩成一个文件。老的sstable文件会在堆积到该文件上的查询请求结束后尽快的删除。这样老的sstable占用的磁盘空间又可以重复使用了。 cassandra2.1改进了压缩后的读性能,通过一种增量式的替换压缩过的sstables。而不是等到整个压缩完才去删除老的sstable。cassandra可以直接从新的sstable中读取,甚至在它完成写入之前。 当数据写到新的sstable,读请求就会访问新的sstable,在老的sstable中相应的数据不会再被访问,并且从系统的page cache中剔除掉。因此当缓存新的sstable的增量过程开始的时候,读取就不会从老的读,相应的cache也会消失。因此可以预见cassandra提供了一种高的性能甚至是在高负载下。 原文地址:https://docs.datastax.com/en/cassandra/2.1/cassandra/dml/dml_write_path_c.html

2016年4月24日 · 1 分钟

[新闻]华为发布P9 & 荣耀4月13日预发布新品

华为于4月6日在伦敦发布华为新旗舰华为P9和P9 Plus: 1、手机摄像的再一次次突破 P9采用徕卡SUMMARIT系列镜头,无论是镜头设计,还是筛选标准均出自徕卡之手,再加上华为的双摄像头成像技术,排除的照片边缘锋利无畸变,细节清晰且丰富,满足徕卡对镜头及图像质量的严苛要求,而且相机自动选择激光对焦,反差对焦等多种对焦方式,表现非同寻常。 2、P系列首款指纹识别机型。 P9引入后背指纹识别,在解锁场景下比普通指纹识别,识别率提升30%。 新加入3D指纹信息提取技术,能有效防止2D假指纹进行支付操作,更安全。 3、外观简约,芯片再升级,麒麟955芯片。 琥珀金、陶瓷白多种精工细琢的外观设计,厚度只有6.95mm,电池有3000MA 麒麟955新片,提升了CPU主频到2.5GHZ,让游戏、视频更流畅。P9自研新的文件系统,可以有效改善手机越来越慢的问题。 华为荣耀 官方微博@荣耀手机,在P9发布第二天,也发布宣传海报: 海报内容是“怕手机慢如蜗牛”,预告4月13日有一个不再怕的开始: 很可能4月13日,荣耀要发布2016年以来首款新品,从手机发布周期看,这款手机很可能是荣耀5C。4月13日,让我们拭目以待。

2016年4月9日 · 1 分钟

Cassandra解决单个磁盘损坏的情况

Cassandra一个节点的磁盘坏了,分两种情况,一种是节点还可以正常启动。另外一种是节点无法启动。 第一种情况:节点还可以正常启动 1、把坏的盘换掉,如果你没有新的盘去更换,你可以在cassandra.yaml里直接把坏的盘注释掉 2、启动cassandra,如果启动的过程中报错,说找不到keyspace之类的,那你应该使用第二种情况的解决方案。 3、使用nodetool repair修复该节点丢失的数据。 第二种情况:节点无法正常启动 1、把坏的盘换掉,如果你没有新的盘去更换,你可以在cassandra.yaml里直接把坏的盘注释掉 2、在正常的节点上执行: $ nodetool ring | grep ip_address_of_node | awk ’ {print $NF “,”}’ | xargs 从而获取到坏掉节点的tokens,把它们(用逗号分割)配置到cassandra.yaml的initial_token 选项中。 3、在cassandra.yaml设置配置项: auto_bootstrap: false 这一步官方文档漏掉了,参考 https://issues.apache.org/jira/browse/CASSANDRA-11365 4、删除你所有数据盘下面的system目录。 rm -fr /mnt1/cassandra/data/system rm -fr /mnt2/cassandra/data/system 。。。。 5、启动cassandra,如果启动的过程中报错,说schema不存在之类的属于正常情况,system库会自动重建,只要节点可以正常加入集群就算正常。 6、同样使用nodetool repair修复该节点丢失的数据。

2016年3月26日 · 1 分钟

[新闻]梅西成为华为全球品牌形象代言人

无论从各大媒体新闻,还是从华为各层主管的微博里,都可以准确得到这个消息:来自巴萨的足球明星梅西正式成为华为全球品牌影响代言人。 一直以来,华为提高赞助和代言人还是比较慎重的,华为喜欢赞助体育运动,特别是足球。这是华为在认真经营自己的品牌形象,宣传自己的企业文化。一个公司的气质是长久积淀下来的。 华为一直秉承的企业文化是“以用户为中心,以奋斗者为本,长期坚持艰苦奋斗" 8 梅西是一个奋斗者的形象,所以华为选择了梅西,同时梅西在全世界的影响力,对于华为全球品牌宣传是有益的。

2016年3月20日 · 1 分钟

slf4j(简单日志门面)日志框架介绍(二)

日志门面的出现,目的就是在任何日志实现框架之间随意切换,而不需要改动一行代码。 所以如果你的代码中使用了slf4j-api打印日志。你可以通过更换适配包实现,更好不同的日志框架。 但是如果你的业务代码,或者依赖的sdk,使用了其它日志框架打印日志,例如commons-logging. 甚至直接使用了log4j等打印日志。怎么样切换到统一的日志框架呢? Slf4j还提供了另外一系列的包:叫做桥接(Bridging)包,原理就是替换log4j,jul,jcl等日志框架的包,把日志导向slf4j。桥接包的原理,就是重写对应日志框架的api和实现,内部使用slf4j打印日志。 下图是slf4j官方提供的: 桥接到slf4j 1、jcl/log4j->slf4j 把对应的commons-logging、log4j包删除。 增加jcl-over-slf4j-1.7.xx.jar和log4j-over-slf4j-1.7.xx.jar包 2、jul->slf4j 因为jdk的logging是无法删除的,所以jul-to-slf4j-1.7.xx.jar是无法通过替换api的方式,实现对jul的替换。它是提供了一个jdk的扩展org.slf4j.bridge.SLF4JBridgeHandler 需要配置到jdk的logger.properties中 handlers = org.slf4j.bridge.SLF4JBridgeHandler 3、log4j2->slf4j Log4j2到slf4j的桥接包,是log4j2官方提供的。叫做: log4j-to-slf4j-2.x.jar 但是log4j2也提供了占位符的形式的日志,所以日志消息也可能会在传递给slf4j之前要先对日志进行格式化,官方文档说这个过程可能存在一定的性能损失。所以不建议这么做。 日志框架切换举例 这样,通过slf4j,我们可以实现任何日志框架之间的切换,而不需要修改代码。举例说明: 1、之前是commons-logging+log4j 打日志,现在想用slf4j+logback打日志。 删除 commons-logging-1.x.jar log4j-1.2.xx.jar 增加 jcl-over-slf4j-1.7.xx.jar slf4j-api-1.7.xx.jar logback-classic-1.1.x.jar logback-core-1.1.x.jar 即可完成切换 2、之前直接用log4j打日志,现在想用log4j2打日志 删除 log4j-1.2.xx.jar 增加 log4j-over-slf4j-1.7.xx.jar slf4j-api-1.7.xx.jar log4j2-api-2.x.jar log4j2-core-2.x.jar 即可完成切换

2016年3月5日 · 1 分钟

JAVA日志框架分类简介

JAVA的日志框架分两类: 一类是日志门面,它定义了一组日志的接口规范,并未提供底层实现。例如slf4j 另外一类是日志实现,它实现日志具体实现,包括日志级别控制,日志格式,打印日志到文件,到屏幕,甚至到数据库等日志的种种具体功能,例如log4j。 日志门面是不能单独使用的,它必须和一种具体的日志实现框架相结合使用。日志门面和日志实现的分离,可以让业务使用不同的日志实现框架之间切换,而不需要改动任何代码,只要掌握日志门面的接口文档,也不需要新的日志实现的接口学习代价。 也就是编码模式里所谓的“门面模式”。 日志实现框架可以直接用于打印日志,但是一般不会这样做,因为这样回带来一定的麻烦,例如一个SDK包使用log4j打日志,而一个业务引用了这个SDK,但是业务开发者喜欢使用logback打日志。那么就会出现一个业务使用两款甚至多款日志框架并存,而且要维护多个日志配置文件的局面。 所以,我们都是用日志门面打日志。

2016年2月21日 · 1 分钟

slf4j(简单日志门面)日志框架介绍(一)

Slf4j的原理 值得一提的是slf4j的作者,同时也是log4j和logback的开发者,名叫Ceki Gülcü。 slf4j和commons-logging的作用和基本原理是一样的,在slf4j-api中提供了两个接口: org.slf4j.Logger org.slf4j.ILoggerFactory 但是相比commons-logging, slf4j有两个不同之处,也可以说为优点: 第一:slf4j对ILoggerFactory的寻找上,是静态绑定,它必须存在一个类org.slf4j.impl.StaticLoggerBinder,指明使用的哪个日志框架,loggerfactory是那个。 为此,slf4j对几乎所有的日志框架都提供一个适配(adaptation)包,里面包含loggerfactory和logger的实现。以及一个org.slf4j.impl.StaticLoggerBinder类 使用slf4j和其它日志框架,只要引入slf4j-api包,以及对应的适配包即可。 下图是官方提供的一张图,slf4j绑定不同的日志实现: 第二:slf4j提供了一种占位符的接口形式,从而避免对字符串不必要的拼接。 举例: 如果用commons-logging打日志: log.info(“my name is” + name +”,my age is ”+ age); 如果log的日志级别配置的是ERROR,那么这句日志就不会输出,但是代码中的字符串拼接操作还是会执行。 为此,我们必须这样写: If ( log. isInfoEnabled() ) { log.info(“my name is” + name +”,my age is ”+ age); } 如果你使用slf4j, 你就可以优雅的这样写: log.info(“my name is {}, my age is {}.”, name, age);

2016年2月21日 · 1 分钟

java通用日志框架commons-logging介绍

commons-logging简称jcl。是apache较早提供的日志通用框架,它规定了一系列的接口, 它可以自动寻找到你的工程里使用的日志框架进行打日志。前提是你要为它提供: org.apache.commons.logging.Log org.apache.commons.logging.LogFactory 两个接口或者是抽象类的实现。 其它日志框架,如果能让commons-logging识别,只能去实现它的接口 org.apache.commons.logging.Log org.apache.commons.logging.LogFactory 并且告诉commons-logging你的LogFactory。 让commons-logging加载你的LogFactory,有两种途径: 第一:设置环境变量 -Dorg.apache.commons.logging.LogFactory=com.huawei.myLogFactory 第二:把com.huawei.myLogFactory写入META-INF/services/org.apache.commons.logging.LogFactory文件中 第三:在classpath下创建一个commons-logging.properties文件写入: org.apache.commons.logging.LogFactory=com.huawei.myLogFactory 其它日志框架,一般使用第二种方式支持commons-logging。Commons-logging对logFactory的寻找过程,可以查阅org.apache.commons.logging.LogFactory类源码. 因为commons-logging是在运行时,通过类查找的方式找到logFactory的实现,并且通过反射的形式获得其实例。所以commons-logging和日志实现框架的绑定是一种动态绑定。 1、commons-logging->log4j/jul 其中:jdk log 和log4j的log和logfactory。commons-logging自己已经提供: Logfactory: org.apache.commons.logging.impl.LogFactoryImpl log: org.apache.commons.logging.impl.Log4JLogger org.apache.commons.logging.impl.Jdk14Logger 所以如果你打算用log4j打日志,只要把log4j的包引入,commons-logging就可以使用log4j打日志了。 如果你不提供log4j的包,commons-logging就默认使用JDK的java.util.logging打日志。 2、commons-logging->log4j2 log4j2 官方提供了commons-logging的Log和LogFactory的实现包。 如果使用commons-logging+log4j2打日志,需要额外引入 log4j-jcl-2.x.jar 包 org.apache.logging.log4j log4j-jcl 2.x 3、commons-logging->logback 很遗憾logback没有提供对commons-logging的支持,因为当logback出现的时候,已经有一个更好的日志门面框架出现了,就是slf4j。

2016年2月20日 · 1 分钟

华为可能要出Matebook手写平板

2月15日 余承东发布一篇微博,内容如下: #今年我要换新的# 北京时间2月21日21点,巴塞罗那MWC2016,为大家带来新品![酷] @华为消费者BG 并附有一张照片: 让人猜测中中,最靠谱的就是盛传已久的华为笔记本,因为很早之前华为就注册了MateBook。根据其注册的信息表示,“MateBook”将被用于便携式计算机用套、计算机键盘、计算机程序(可下载软件)、平板电脑、计算机硬件、数据处理设备、智能手机、调制解调器等等产品,从商标名称及用途来看,“MateBook”无疑就是为其PC产品准备的。 从这幅照片上看,这应该不是一款传统意义上的笔记本。估计是一款平板电脑两用,并且带手写笔的产品。 参考苹果,应该是和ipad对齐的一款产品。因为苹果在去年九月发布了ipad pro,同时为其配备了专业的Apple Pencil。那么MateBook应该是一款类似的产品。据悉华为将和PC端最牛逼的Intel合作,搭载Intel处理器。可能会支持Windows和Andriod双系统。 总之这是一款让人期待的产品。此外已知MWC2015,华为发布了荣耀2X,这一次还有可能要发布荣耀3X.让我们静静的等待华为带给我们的科技惊喜。

2016年2月16日 · 1 分钟

如何安全升级wordpress

第一步:备份 如果真到了升级后一团糟的底部,有了备份的数据,还可以重头再来。 备份分两部分: 第一部分是代码备份,对整个根目录打包存放到安全的位置 tar zcvf backup_dir/backup_20160124.tar.gz /home/wordpress/html 第二部分是数据库备份 mysqldump -u username -ppassword yourdatabase > backup_20160124.sql 第二步:本地环境搭建 在本地机器上搭建一套apache+php+mysql系统。在windows机器上,可以直接安装个省事的WAMP(Windows+APACHE+MYSQL+PHP)。 然后把备份的数据库导入到本地的机器,把备份的代码解压到apache的工作目录。 设置本地hosts,举例: 127.0.0.1 zhaoyanblog.com 浏览器访问http://zhaoyanblog.com 就是访问的本地环境。 第三步:wordpress升级演练 wordpress升级有两种形式: 一种是通过wordpress的管理后台进行升级。 另外一种是把wordpress最新安装包下载下来,把其中的wp-content删除,然后用其覆盖当前的代码。 然后访问http://zhaoyanblog.com/wp-admin/upgrade.php进行其它升级(比如数据库数据)。 最后访问本地http://zhaoyanblog.com,确认升级是否有问题。 第四步:正式环境升级 当本地升级没有问题之后,把在本地的升级步骤,再实施到正式的环境即可。 最后说一句 wordpress好多版本是为了解决老版本中的安全问题,所以时间长了wordpress的版本升级还是很有必要的。

2016年1月24日 · 1 分钟

博客适配移动浏览器

博客使用了wordpress,虽然大部分wordpress的主题都是响应式布局,也就是随着客户端屏幕大小,语言进行自由适配,但是总是不完美的。 用wordpress,首先想到的就是用插件解决这个问题。发现wptouch这款插件的页面是最舒服的一款适配移动的插件。 wptouch是专门用来解决wordpress的移动端浏览的问题,它有自己专门的主题。功能强大。 wptouch只提供基础的功能,强大的主题功能需要付费升级到pro版本。 当然wordpress适配移动端,还有其它方式,举例说: 安装专门的移动主题,然后使用wordpress-mobile-theme-switcher等插件,根据User-agent进行动态主题切换。

2016年1月17日 · 1 分钟

SUSE配置SDK安装源

当你编译一个开源软件的时候,例如nginx、php,他可能需要依赖很多开源库,一种做法是去官方网站上下载,自己编译。 但是新的开源库,可能又依赖另外一个开源库,你会发现自己陷入一个二叉树。。。。 还是使用系统的应用管理软件去直接安装开发包,是最方便的,例如SUSE的zypper。编译的时候依赖哪个包就安装哪个包, zypper帮你自动下载安装它所依赖的其它库。 一个开源库,有两个jar包,一个普通的包,一个是开发包(会包含编译用的头文件)。举例zlib库。 一个是zlib包,一个zlib-devel包。系统的安装盘里,只有zlib包,zlib-devel包是在SDK盘里。 SUSE的SDK安装源是非常难找啊,但是还是被我找到一个: 如果你和我一样使用的SUSE 你所需要的安装源,可以在http://demeter.uni-regensburg.de这个网站找这个SDK盘的安装源。 比如,我用的是SLE11SP3,对应的SDK安装源就是http://demeter.uni-regensburg.de/SLE11SP3-SDK-x64/DVD1/ 现在做的就是配置到zypper里: vi /etc/zypp/repos.d/SLES11-SP3-SDK.repo 输入: [SLES11-SP3-SDK] name=SLES11-SP3-SDK enabled=1 autorefresh=1 baseurl=http://demeter.uni-regensburg.de/SLE11SP3-SDK-x64/DVD1/ path=/ type=yast2 keeppackages=0 这样你就可以安装zlib-devel等开发包了: zypper install zlib-devel 再去编译nginx、php等其它开源软件,就不会有少依赖库的问题了。

2016年1月9日 · 1 分钟

博客正式从apache迁移至nginx

从apache迁移到nginx,主要有以下几个方面的事情: 1、编译php和nginx 编译php的参数: ./configure –prefix=/usr/local/php5 -with-config-file-path=/usr/local/php5/etc –enable-fpm –enable-pcntl –enable-mysqlnd –enable-opcache –enable-sockets –enable-sysvmsg –enable-sysvsem –enable-sysvshm –enable-shmop –enable-zip –enable-ftp –enable-soap –enable-xml –enable-mbstring –disable-rpath –disable-debug –disable-fileinfo –with-mysql –with-mysqli –with-pdo-mysql –with-pcre-regex –with-iconv –with-zlib –with-mcrypt –with-gd –with-mhash –with-xmlrpc make make install 编译php关键的是要加–enable-fpm参数,因为nginx不像apache有php插件,可以直接调用php。nginx是通过fast-cgi连接php服务,php服务是通过fpm启动的,php的其它模块最好也编译进去,不知道wordpress会用到什么模块,否则又要重新编译。 编译nginx ./configure –prefix=/usr/local/nginx make make install nginx 没有什么选项要指定,直接编译就好了。 2、启动php-fpm cp /usr/local/php5/etc/php-fpm.conf.default /usr/local/php5/etc/php-fpm.conf 编辑配置文件:/usr/local/php5/etc/php-fpm.conf 一个是用户和群组: user = zhaoyanblog group = users 一个是端口 listen = 127.0.0.1:9000 最后启动就可以了: /usr/local/php5/sbin/php-fpm 3、启动nginx 编辑配置文件:/usr/local/nginx/conf/nginx.conf 添加http选项,增加压缩选项: gzip on; #启动压缩的最小报文大小 gzip_min_length 1k; #压缩所使用的缓存 gzip_buffers 4 16k; #压缩等级1表示最快,9表示最好 gzip_comp_level 2; #压缩支持的content-Type类型 gzip_types text/plain text/javascript application/x-javascript text/css text/xml application/xml application/xml+rss application/javascript; 里server里配置: ...

2016年1月9日 · 1 分钟

我看好老罗

首先我相信老罗的底线是手机的质量必须没有问题,从老罗和王自如的辩论中就可以看出来,当老罗看到了王自如的评测的时候,他一开始真的以为自己的工程师犯了一些低级错误,首先是没有好脸色的去和自己的工程师去沟通。一个英语出身的外行,要把所有的设计细节学习清楚,再去和王自如挨个争辩,由此看来,老罗是很认真的。 老罗最关注的是用户体验,他的想法很简单,就是想做一个像苹果那样,甚至比苹果看起来更好用的手机,所以他很看重细节,他亲自过问OS里的每一处设计和用户感受,两次发布会都是大篇幅讲解用户体验,讲锤子手机更用户带来哪些哪些好用和便利,而不是讲CPU到几核了,性能翻几倍了,内存又到多大了,他所关心的都是用户的最直接的使用感受。 老罗是个完美主义者,也许老罗是处女座的,至少在锤子手机的外观上是这样的,他要求他的锤子手机必须是左右对称的,前后面板干净的,为此他是绞尽脑汁把传感器藏到听筒里,左右各放一个音量控制键,前后都是玻璃,连背后的锤子logo都镀的那么完美无瑕,这次T2又把卡槽和音量键结合到了一起,把电源键整合到了home键上,就是为了整个金属中框连续无断点,最符合中国人的审美观。 老罗是务实的,他知道他的公司需要是专业人才,所以他不辞辛苦去挖人才,找设计师,他是极度的信任和仰仗他的员工,他说真正的工匠是他的工程师们,他不过是工匠精神的吉祥物,为了品牌的宣传,这样一个个性张扬的人,在微博上也平静了下来,两次发布会的门票,一次捐给了openssl,一次捐给了openresty,我想这应该也是他的工程师们的建议,这样的情怀,我相信会让更多的技术人员走到老罗麾下。 T2发布后,一些不良媒体又在看低锤子,说没有最新的CPU,没有指纹识别,没有快充等等,我觉得T2是一件艺术品,它本身追求的就不是这些东西,T2真的很漂亮,虽然我不是老罗的粉丝,但是我看好老罗。

2016年1月2日 · 1 分钟