Freebase 数据库实践

Freebase是一个知识库,由人提交对现实事物的描述组成这个庞大的知识库。由于Freebase有结构化的性质(不像搜索引擎),可以通过Freebase进行知识推理。详见Wikipedia。类似的有Yago,Cyc等,我感觉还是Freebase最完善。Freebase用的是MQL来进行读写数据库。但是不清楚他们用的什么数据库架构,我觉得肯定不是简单的关系型数据库。

数据库课程的实践任务是通过Freebase的dump data用关系型数据库重新构建,当然没有在线的那么完善的功能。这些数据为24G,解压缩后大概300G。所以可以看出总共的信息量不超过24G。从数据描述也可以看出有很多重复。如下是文件的数据格式。

Topic:

理清建模的思路,必须了解freebase到底是什么。通过google的api wiki和freebase的wiki,我知道其中的节点就是Entity(Topic)。然后根据freebase的主页可以看到目前有46,236,787个Topic。所以地一件事就是找出所有Entity,通过Topic wiki,可以知道每个Topic都有一个GID和MID,GID已经不用了。所以找MID即可,如m.045c7b。这大概有8千万个,但是不是每个mid都是topic,还要满足是common.topic的type,因此去掉不满足条件的剩下4千多万个,符合实际。这也大大降低了难度。有了这些mid后,我觉得不能用字符串来作为数据库的主键,因此根据wikimid,这些mid都是32进制的数,很容易就转换为Int型,索引和空间效率都大大提高。(yt同学直接压缩字符的长度,也是吊,可以通过用户输入的部分MID,预测要输的完整MID)

Description:

有了Topic的MID,就可以以此为中心来开展工作了。首先是看看freebase里的Topic的schema。我感兴趣的是Description,Image(这里只有一个链接,还需要手动通过google取得图片,如google,后来发现Image很少,因此放弃)。通过sed直接过滤即可。

Name:

每个object在freebase里都有name,而且是各种各样的name。我们只关心type.object.name,同样用sed可以完成这个工作。大概90%的Topic都有英文name。要求是要根据输入的来查询相关的topic。这里我们要做的就是fulltext。幸运的是InnoDB,已经支持fulltext (最后解释为什么用InnoDB)。在这里我们做的一个主要优化是把这个表放到SSD上,速度就提高了10倍以上,只能说SSD吊。

Entity Relation:

不管老师的实际要求是什么,我觉得要做就得牛X。老师的几个要求意义不大,不有趣。比如找出跟Entity相关的所有object,完全没有意义,不过就是增大了数据库大小。其他要求也不提了,我就说说我们组的比较吊的一点:找出所有和指定Topic相关的Topic,并给出是什么关系。这个的挑战有两个,一个是得到所有有两个MID的元组后,去掉不是Topic的元组。二是如何表现这个联系。

第一个问题解决方法:全部找出来后,先按第一个topic的mid排序,与所有topic的排好序的mid比较,去掉不是topic的元组。再按第二个topic的mid排序,与所有topic的排好序的mid比较,去掉不是topic的元组。相当于两次sort-merge-join,复杂度为2Nlog(N)+log(M)+2(N+M)。还是能接收的,事实也证明linux的sort命令很吊。

第二个问题解决方法:采用d3.js库。可视化查询,本来想做到,按一下topic,自动平滑的扩展相关的topic,但是还是太弱,没有完成,只能不平滑的进行跳转。如下的效果。

baidu
baidu topic in freebase

Final:

根据要求和一些自己的想法,我们构建的数据库模型如下。为了存储效率,我们牺牲了一点查询效率,很多查询都需要join3个表。另外我们采用InnoDB,不可否认这在批量插入的时候确实比较慢, 比较是行级锁,但InnoDB是未来,必须好好了解其特性,而且InnoDB支持外键,为了完美,果断InnoDB。另外为了适应InnoDB和要求,还得修改一下my.cnf,可以提高缓存和排序效率。

freebase
freebase relation

最后的数据库,共935,874,169条记录,共72.1GB。各表分布如下。在这过程中,走了不少弯路,因此也产生不少中间文件,只能说多亏了linux简单的命令如sort、grep、 sed、awk、 split,在windows真不知道怎么搞,只能自己写c处理。data

 

实用SSH

已经1个多月没有更新了,上个月突然就事情多了。比如开学交报告,面试工作,然后就是保研了。当然还有其他事,简直麻烦。现在成了保研狗,之前还信誓旦旦说要工作,现在仔细想想,确实现在准备还不充分,1写代码能力还很差,2没有在某个专业有很深的研究。所以还得在读研期间好好学习。


 

SSH在Linux下,是个绝好的东西。因此很有必要进一步掌握它,而不仅仅是只会ssh登录主机。我直接就看了一本书,叫SSH: The Secure Shell The Definitive Guide。我在这里介绍一点其中的精华和比较实用的技巧以及一些SSH高级特性,详细的还得参考书籍。

escape sequences

这是我之前从来没有听说过的,但是却很好用,所以看书还是很有用的。在ssh中同样有转义字符,通常是~。可以在登录ssh后,按下 ~? 来查看用法,会出现以下内容:

我觉得最有用的是 ~^Z ,可以暂时挂起ssh连接,可以使用jobs查看效果,然后fg,重新连接。

ssh-config

直接 man ssh_config ,就能获取大量有用配置。想想现在我有7、8台主机,我还要记IP什么的,很麻烦。最初的做法是用alias,后来发现真是弱爆了。这个只能用来登录什么的,scp就没办法了。使用ssh-config只要创建一个 ~/.ssh/config 文件,然后怎么配置就可以看man,或者参考Simplify Your Life With an SSH Config File。以下是个例子:

这样就方便多了,无论scp还是ssh,都能直接使用 ssh aws  ,如此简洁的命令。

ssh-keygen

我相信很多人的密钥都没有密码,什么意思呢?就是ssh host时,不需要输入密码。其实这是很不安全的。当然现在还来得及补过,只要 ssh-keygen -p -f .ssh/id_rsa 就能在原key的基础上加上一个密码。以下还有一些关于ssh-keygen的用途:

  • ssh-keygen -l -f ~/.ssh/known_hosts    查看本机登录的主机及其指纹
  • ssh-keygen -f .ssh/id_rsa.pub -e -m pem > .ssh/id_rsa_pub.pem  生成pem格式的公钥

ssh-agent

确实id_rsa有密码有时会很不方便,这时可以用ssh-agent解决。我还没有意识到这个问题,所以还没怎么使用,有兴趣的可以参考ssh-agent

scp

这也是非常有用的命令,结合ssh config,我最常用的命令一共3条。

  1. scp aws:text1 text1  从服务器上cp到本机
  2. scp text2 aws:text2  从本机cp到服务器
  3. scp -rp aws:/home/ubuntu ./ubuntu  cp目录并保持权限

exec command

有时登录ssh,只是为了运行一个命令,那么可以简单直接运行。最简单的是 ssh aws ls -al ,当然也有在本地运行命令,然后保存结果到服务器。如 ls -la | ssh aws 'cat > test' 。如果运行的命令比较复杂,则可以通过linux常用方法批量运行。

X11

ssh也支持图像化(X11),首先要在服务器端启用X11 forwarding,当然还要有相应的库。本机执行 ssh -Y aws ,然后试试xterm看看有没有图像,然后接着操作其他高级的图像界面。为了安全起见,最好不要启用X11,实在要用也可以使用vnc。

有时为了远程运行一个图形界面的程序,并且ssh退出后不打断图形程序的运行。比如运行一个bt程序。首先要 export DISPLAY=:0 ,表明使用远程主机的DISPLAY (简单来说,DISPLAY会被设置为localhost:10.0,类似的。10表示监听端口为6000+10,0表示第一个screen,远程主机将图形信息发送的6010,ssh则负责转发到本地),然后使用nohup,如 nohup vuze &

forwarding

这也是ssh不得不说的吊功能。不但可以用来加密,还可以用来穿透防火墙,或者说翻墙。具体有local forwarding,remote forwarding,dynamical forwarding。具体看前一篇,DNS配置

match

如果有个用户比较特别,允许其用密码登录,其他不能用密码登录。Match就能发挥作用了。详细查看man ssh_config. 简单最常用的配置如:

注意match下的规则,是从match下一直结束或者遇到下一个match,小心操作,登不上去就麻烦了。

subsystem

这是ssh的特性之一。最常用的是sftp。然后又发展出sshfs,就是以ssh形式挂载远程文件目录。这体验跟网速延迟有很大关系。延迟小网速快,体验就非常好,跟本地磁盘差不多。简单用法: sshfs -o IdentityFile=/home/york/.ssh/RH-Hadoop.pem ubuntu@54.64.60.106: ~/tmp 其他可以参考sshfs.

这个功能在局域网里简直算吊炸。比如我远程挂载了一个目录/opt,里面有matlab。我就可以在本地执行matlab了。爽不爽。

restart

为了使配置生效,必须重启sshd。这个很讨厌,如果不小心配置错了,登不了服务器就麻烦了。如果能不打断连接的情况下,重启sshd就好了。这点开发者早就想到了。可以用如下命令重启。

reverse ssh

如果你有一台内网机器A(外网无法直接ssh到A),但有一台外网机器B(可以从A直接ssh连接到B),当你要在外网ssh连接A时,就是reverse ssh的用武之地。具体如下:

其中20002端口可以设置成任意其他空闲端口。perfect!

 

链接:

  1. Why passphrase
  2. ssh configSimplify Your Life With an SSH Config File
  3. converting-openssh-public-keys

 

我很高兴有人通过博客联系我。我之前没有外链,纯粹通过搜索引擎。有人能到这里就说明我的内容还是有用的,这也是写博客的动力之一。现在我决定分享到g+和twitter,虽然也没有多少好友。

traceroute 路由追踪

       一个数据包从你的电脑出发,然后达到目的地,比如google。中间到底经历了什么?我能不能看到它路过的路由器?traceroute可以做到。

       traceroute原理简单说来,就是利用TTL(time to live,设置数据包最大生存时间,用来防止数据包在路由器间循环)。主机先给数据包设置一个TTL,然后这个数据包每经过一个路由器,路由器就把TTL减一。直到递减到零,这时,路由器会发送回来一个ICMP Time Exceeded,这个时候主机接收到之后,就知道相应的路由器IP了。

       traceroute是linux自带的。详细用法见man。下面是最实用的命令。类似的工具还有tracepath,但是感觉traceroute更好。

       只有这个功能,感觉不太好用,如果能知道ip的真实世界的地址就好了。比如中国上海这样的。正好网上出了个开源的GeoIP(IP与地理地址转换)。非常感谢作者。

      然后胶水语言python就上台了。我就直接贴代码了,很好理解。注意这是不能直接运行的,需要下载相应的GeoIP,然后写个geoip来解析IP与地理地址。

 效果图:

cpu30

链接: