<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>zhiwensun's blog</title>
    <description></description>
    <link>/</link>
    <atom:link href="/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Thu, 30 Nov 2017 06:07:16 +0000</pubDate>
    <lastBuildDate>Thu, 30 Nov 2017 06:07:16 +0000</lastBuildDate>
    <generator>Jekyll v3.6.2</generator>
    
      <item>
        <title>Install Tensorflow</title>
        <description>&lt;h1 id=&quot;how-install-tensorflow-on-ubuntu-1604&quot;&gt;How install Tensorflow on Ubuntu 16.04&lt;/h1&gt;

&lt;h2 id=&quot;step-1-install-python-3&quot;&gt;Step 1: Install Python 3&lt;/h2&gt;

&lt;p&gt;Update your repository list first:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt-get update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, install Python 3, Python 3 have better performance than Python 2:&lt;/p&gt;

&lt;p&gt;apt-get install python3-pip python3-dev python-virtualenv&lt;/p&gt;

&lt;h2 id=&quot;step-2-setup-python-3-env-for-tensorflow&quot;&gt;Step 2: Setup Python 3 env for tensorflow&lt;/h2&gt;

&lt;p&gt;Setup a separated env for tensorflow&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;virtualenv --system-site-packages -p python3 ~/tensorflow

source ~/tensorflow/bin/activate
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Update pip first to make sure pip &amp;gt;= 8.1&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip install --upgrade pip
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-3-confirming-the-installation-of-tensorflow&quot;&gt;Step 3: Confirming the installation of tensorflow&lt;/h2&gt;

&lt;p&gt;Install tensorflow without GPU version:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;pip install --upgrade tensorflow
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-4-confirming-the-installation-of-tensorflow&quot;&gt;Step 4: Confirming the installation of tensorflow&lt;/h2&gt;

&lt;p&gt;Create a example python to test&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vi /tmp/tf-example.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Enter code as following ：&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import tensorflow as tf
hello = tf.constant('Hello, Tensorflow!')
print(tf.Session().run(hello))
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Run it :&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;source ~/tensorflow/bin/activate
python /tmp/tf-example.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You will now see a output like:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;b'Hello, Tensorflow!'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Congrats! You have now installed Tensorflow!.&lt;/p&gt;
</description>
        <pubDate>Wed, 22 Nov 2017 00:00:00 +0000</pubDate>
        <link>/install-tensorflow/</link>
        <guid isPermaLink="true">/install-tensorflow/</guid>
        
        
      </item>
    
      <item>
        <title>Move blog to github pages.</title>
        <description>&lt;blockquote&gt;
  &lt;p&gt;“something:”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;TF&lt;/li&gt;
  &lt;li&gt;CNN&lt;/li&gt;
  &lt;li&gt;GPU&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 11 Nov 2017 00:00:00 +0000</pubDate>
        <link>/to-githubpage/</link>
        <guid isPermaLink="true">/to-githubpage/</guid>
        
        
      </item>
    
      <item>
        <title>Arduino操作74HC595</title>
        <description>&lt;p&gt;&lt;!--?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?--&gt; 74HC595是一个寄存器，他能够将串行的输入累积成一次并行的输出。要做的测试就是通过一个输入pin来控制多个输出pin的状态。&lt;/p&gt;
&lt;p&gt;pin14就是接收arduino主板串行的输入，比如：&lt;/p&gt;
&lt;p&gt;pin14输入1，且bitorder设置为MSBFIRST，则Q0输出为1，Q1  - Q7都输出为0&lt;/p&gt;
&lt;p&gt;pin14输入3，且bitorder设置为MSBFIRST，则Q0、Q1输出为1，Q2  - Q7都输出为0&lt;/p&gt;
&lt;p&gt;pin14输入255，且bitorder设置为MSBFIRST，Q0  - Q7都输出为0&lt;/p&gt;
&lt;div&gt;可以说将pin14的输入转成一个二进制数，Q0 - Q7分别是他们的第1位 - 第8位。&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;操作74HC595，最简单的操作方法当然是使用shiftout，官方就有示例：http://arduino.cc/en/Tutorial/ShiftOut&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;当然，还可以使用更加高效的SPI库来操作：其实操作起来也很简单&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;pinMode(SS, OUTPUT)&lt;/div&gt;
&lt;div&gt;SPI.begin()&lt;/div&gt;
&lt;div&gt;SPI.setBitOrder(MSBFIRST)&lt;/div&gt;
&lt;div&gt;然后是根据需要调用&lt;/div&gt;
&lt;div&gt;digitalWrite(SS, LOW)&lt;/div&gt;
&lt;div&gt;SPI.transfer(data)&lt;/div&gt;
&lt;div&gt;digitalWrite(SS, HIGH)&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;需要注意的是几根pin的对应&lt;/div&gt;
&lt;div&gt;SS Slave Select（默认arduino上的10） 就是 74HC595中的 pin12&lt;/div&gt;
&lt;div&gt;MOSI（默认arduino上的11） 就是  74HC595中的 pin14&lt;/div&gt;
&lt;div&gt;CLK（默认arduino上的13） 就是  74HC595中的 pin11&lt;/div&gt;
&lt;div&gt;MISO 在本示例无需连接，如果要arduino接收数据，就是 74HC595中的 pin9&lt;/div&gt;
&lt;div&gt;&lt;/div&gt;
&lt;div&gt;参考资料&lt;/div&gt;
&lt;div&gt;http://arduino.tw/articlesindex/extend-io/213-74hc595.html&lt;/div&gt;
</description>
        <pubDate>Tue, 05 Mar 2013 00:06:37 +0000</pubDate>
        <link>/arduino_74hc595/</link>
        <guid isPermaLink="true">/arduino_74hc595/</guid>
        
        <category>arduino</category>
        
        
        <category>技术记录</category>
        
      </item>
    
      <item>
        <title>一个计算联通通话计费时间的脚本</title>
        <description>&lt;p&gt;其实联通网站上的累计通话时间和实际计费的时间差不多。&lt;/p&gt;
&lt;p&gt;如果要准确的统计，那得依赖些脚本了。&lt;/p&gt;
&lt;p&gt;从联通的网站上面把通话记录复制出来，放到一个文件中，如 /tmp/x 然后保存以下代码到一个shell文件calllog.sh。&lt;br /&gt;
然后执行 cat /tmp/x | bash calllog.sh，最后就可以看到通话时间了。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;awk '$4 != &quot;被叫&quot; &amp;amp;&amp;amp; $5 != &quot;10010&quot;{&lt;br /&gt;
print $0;&lt;br /&gt;
pos1 = index($3, &quot;分&quot;);&lt;br /&gt;
pos2 = index($3, &quot;秒&quot;);&lt;br /&gt;
min=0&lt;br /&gt;
if (pos1 &amp;gt; 0) {&lt;br /&gt;
min = substr($3, 1, pos1-1);&lt;br /&gt;
#    print &quot;min:&quot; min;&lt;br /&gt;
}&lt;br /&gt;
if (pos2 &amp;gt; 0) {&lt;br /&gt;
min = min + 1;&lt;br /&gt;
}&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt; &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;print &quot;tmin:&quot;, min;&lt;br /&gt;
total += min;&lt;br /&gt;
}&lt;br /&gt;
END {&lt;br /&gt;
print &quot;total:&quot;, total;&lt;br /&gt;
}&lt;br /&gt;
'&lt;br /&gt;
&lt;/code&gt;&lt;/p&gt;
</description>
        <pubDate>Thu, 24 Jan 2013 22:32:27 +0000</pubDate>
        <link>/unioncom/</link>
        <guid isPermaLink="true">/unioncom/</guid>
        
        <category>shell</category>
        
        
        <category>技术记录</category>
        
      </item>
    
      <item>
        <title>php中的curl几点需要注意的地方</title>
        <description>&lt;p&gt;&lt;strong&gt;1 CURLOPT_POSTFIELDS中的玄机&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;curl_setop($ch, CURLOPT_POSTFIELDS, $var);  但不知道内有玄机，php的doc里面有这么一段话。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;If value is an array, the Content-Type header will be set to multipart/form-data.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;要知道一般POST时，会以application/x-www-form-urlencoded 的 Content-Type POST。而 multipart/form-data 一般用于上传文件。&lt;/p&gt;
&lt;p&gt;关于两者的区别，不想读rfc的可以先看看 http://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data&lt;/p&gt;
&lt;p&gt;两种情形下POST样例：&lt;/p&gt;
&lt;p&gt;application/x-www-form-urlencoded 形式的POST&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;POST / HTTP/1.1&lt;br /&gt;
Host: 192.168.201.197&lt;br /&gt;
Accept: */*&lt;br /&gt;
Accept-Encoding: gzip&lt;br /&gt;
Content-Length: 8&lt;br /&gt;
Content-Type: application/x-www-form-urlencoded&lt;/p&gt;
&lt;p&gt;url=xxxx&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;multipart/form-data 格式的POST：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;POST / HTTP/1.1&lt;br /&gt;
Host: 192.168.201.197&lt;br /&gt;
Accept: */*&lt;br /&gt;
Accept-Encoding: gzip&lt;br /&gt;
Content-Length: 153&lt;br /&gt;
Content-Type: multipart/form-data; boundary=----------------------------e62c3de4a033&lt;/p&gt;
&lt;p&gt;Content-Disposition: form-data; name=&quot;url&quot;&lt;/p&gt;
&lt;p&gt;xxx&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;2 curl中PUT文件&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;现在都流行RESTful的接口，很多接口要求客户端PUT方式上传文件。在php中，使用curl发起PUT的请求，有两种方法：&lt;/p&gt;
&lt;p&gt;curl_setopt($ch, CURLOPT_PUT, 1);&lt;br /&gt;
或者&lt;br /&gt;
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');&lt;/p&gt;
&lt;p&gt;当你想使用PUT上传文件时，请不要使用第二种，因为它不会上传文件。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</description>
        <pubDate>Sun, 02 Dec 2012 13:55:02 +0000</pubDate>
        <link>/php_curl/</link>
        <guid isPermaLink="true">/php_curl/</guid>
        
        <category>php</category>
        
        <category>curl</category>
        
        
        <category>技术记录</category>
        
      </item>
    
      <item>
        <title>关于bash的启动运行的文件</title>
        <description>&lt;p&gt;工作上经常碰到环境变量不对，bash运行行为和自己期望的不一致，于是想花点时间看看bash.&lt;/p&gt;
&lt;p&gt;说起来，这件事情应该再简单不过了，看看bash手册上写的便是了.&lt;/p&gt;
&lt;p&gt;http://www.gnu.org/software/bash/manual/bashref.html#Bash-Startup-Files&lt;/p&gt;
&lt;p&gt;但是坦白来说，我花了很长时间才看明白了一点.&lt;/p&gt;
&lt;p&gt;看到的一些结论&lt;br /&gt;
如果是login的shell，那么bash在运行先执行 /etc/profile ；然后依次查找 ~/.bash_profile, ~/.bash_login, ~/.profile；如果找到其中一个文件就执行之，后面的就不执行了.&lt;/p&gt;
&lt;p&gt;如果是interactive的非login shell，则先会执行 /etc/bash.bashrc，如果~/.bashrc存在的话，接着执行~/.bashrc.&lt;/p&gt;
&lt;p&gt;如果是非interactive的，且非login shell，则执行 $BASH_ENV 对应的shell.&lt;/p&gt;
&lt;p&gt;ssh到远端的机器，远端机器上的bash会执行什么呢？如果是login shell，不用说，和第1种一样；如果是ssh remote-machine 'cmd'这种的（也就是我们一般shell脚本里面调用形式），则会执行~/.bashrc（远端机器上的bash在编译bash的时候define了SSH_SOURCE_BASHRC ）.&lt;/p&gt;
&lt;p&gt;有些问题&lt;br /&gt;
什么是interactive shell，什么是login shell&lt;/p&gt;
&lt;p&gt;interactive shell就是顾名思义，有用户交互的，检查方法就是在命令行下执行 echo $-，如果有i这个选项，则就是interactive shell 了.&lt;/p&gt;
&lt;p&gt;login shell简单来说就是bash启动的时候加了 -l选项.&lt;/p&gt;
&lt;p&gt;举几个实际的例子：&lt;/p&gt;
&lt;p&gt;interactive &amp;amp; login shell:&lt;/p&gt;
&lt;p&gt;linux登录到真实的终端tty1&lt;/p&gt;
&lt;p&gt;interactive &amp;amp; non-login shell:&lt;/p&gt;
&lt;p&gt;打开终端模拟器，在终端模拟器里面执行/bin/bash -i cmdfile&lt;/p&gt;
&lt;p&gt;non-interactive &amp;amp; login shell&lt;/p&gt;
&lt;p&gt;在终端模拟器里面执行/bin/bash -l cmdfile&lt;/p&gt;
&lt;p&gt;non-interactive &amp;amp; non-login shell:&lt;/p&gt;
&lt;p&gt;在终端模拟器里面执行/bin/bash cmdfile&lt;/p&gt;
&lt;p&gt;为什么我在手动在机器上可以ssh到远端机器的，但是在shell脚本里面不行？&lt;/p&gt;
&lt;p&gt;这种情形出现在ssh到远端机器的private key是有passphase 的，简单来说，ssh 到远端机器的时候，你还需要输入这个pass phase的，那为什么你一般ssh到远端机器的时候不要输入passphase呢，这个就是ssh-agent的功劳了，ssh通过环境变量中的SSH_AUTH_SOCK和SSH_AGENT_PID获得真实的private key。&lt;/p&gt;
&lt;p&gt;简单来说，因为这个时候有了SSH相关环境变量。这些环境变量一般在通过keychain设置的，而keychain一般是startup脚本里面执行的。 解决办法就是bash -l.&lt;/p&gt;
&lt;p&gt;骗人吧，按你的说法，ssh过去要执行~/.bashrc的，但是我~/.bashrc里面的命令没有执行&lt;/p&gt;
&lt;p&gt;应该.bashrc里面有一段话，[ -z &quot;$PS1&quot; ] &amp;amp;&amp;amp; return 也就是说，如果是非interactive的时候，PS1不会被设置，然后就return了，后面的命令当然没有执行.&lt;/p&gt;
&lt;p&gt;interactive &amp;amp; login 的shell怎么也执行 ~/.bashrc 了？&lt;/p&gt;
&lt;p&gt;看看 ~/.bash_profile, ~/.bash_login, ~/.profile 这几个文件中，应该有写&lt;/p&gt;
&lt;p&gt;if [ -f &quot;$HOME/.bashrc&quot; ]; then&lt;br /&gt;
    . &quot;$HOME/.bashrc&quot;&lt;br /&gt;
fi&lt;br /&gt;
ssh remote-machine 'cmd' 为什么不行啊？&lt;/p&gt;
&lt;p&gt;一样的道理，PATH环境变量不是在 ~/.bashrc里面设置的.&lt;/p&gt;
&lt;p&gt;ssh remote-mache 'cmd' 的时候不执行~/.bashrc啊？&lt;/p&gt;
&lt;p&gt;编译bash的时候没有define SSH_SOURCE_BASHRC.&lt;/p&gt;
&lt;p&gt;我的cmdfile在shebang部分里面已经声明了#!/bin/bash -l 了，但是它表现的不是login shell&lt;/p&gt;
&lt;p&gt;不要使用 /bin/bash cmdfile 这种方式运行，要么使用cmdfile直接运行，要么使用/bin/bash -l cmdfile运行.&lt;/p&gt;
</description>
        <pubDate>Sat, 01 Dec 2012 21:19:07 +0000</pubDate>
        <link>/bash_startup_files/</link>
        <guid isPermaLink="true">/bash_startup_files/</guid>
        
        <category>bash</category>
        
        
        <category>技术记录</category>
        
      </item>
    
      <item>
        <title>hive相关</title>
        <description>&lt;p&gt;最近一直使用hadoop hive做数据分析，遇到一些问题，也收获一些，记一下。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一些经验和大家分享：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1 使用external table会比较方便管理，将数据放到hdfs中，然后再基于hdfs建external表，这样你可以随心所欲的管理你的数据，可以使用hive的external table来查询，也可以自己直接写mapreduce job来处理；使用external table的另外一个好处是可以随便改变table的schema，因为在drop table时数据不会丢失；只是删除元信息，所以，如果schema需要调整，删掉重新建就是了。&lt;/p&gt;
&lt;p&gt;2 能使用hql做的事情还是用hql吧，写mapreduce毕竟麻烦，数据调试是个问题。&lt;/p&gt;
&lt;p&gt;3 hql和sql还是有些地方不一样的，比如group by的时候不能用column的alias，详情可以参考我的这个&lt;a href=&quot;http://stackoverflow.com/questions/13470238/hiveql-udf-and-group-by/13489094#13489094&quot;&gt;回答&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;4 hql里面的条件可以随便的使用like '%%' 了，因为基本上所有的hql都会转换成mapreduce job，所以，你使用like '%%'只是在map的时候稍微多了点计算量而已。&lt;/p&gt;
&lt;p&gt;5 hwi玩玩还可以，但是无法真正用于生产环境：结果默认保存到内存中；输入的hql有错又不知道是什么错；跑一段时间会挂掉；界面极度难用等等，这些问题都是它被正式使用的障碍。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一些问题的解决方法：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;hive报metadata错：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;
FAILED: Error in metadata: javax.jdo.JDOFatalInternalException: Unexpected exception caught.
NestedThrowables:
java.lang.reflect.InvocationTargetException
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask
&lt;/pre&gt;
&lt;p&gt;解决方法：删掉 $HADOOP_HOME/build ，这种情况很有可能是大家的hadoop用的是src版本，然后编译出来有build，具体为什么会因此报错，还不得而知。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;hadoop datanode无法启动：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个主要是mac os上会遇到，在$HADOOP_HOME/logs/*datanode*out 中看日志，会发现有：&lt;/p&gt;
&lt;pre name=&quot;code&quot;&gt;Unable to load realm info from SCDynamicStore&lt;/pre&gt;
&lt;p&gt;在$HADOOP_HOME/conf/hadoop-env.sh 中设置一下HADOOP_OPTS即可&lt;/p&gt;
&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;export HADOOP_OPTS=&quot;-Djava.security.krb5.realm=OX.AC.UK -Djava.security.krb5.kdc=kdc0.ox.ac.uk:kdc1.ox.ac.uk&quot;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;hwi无法启动：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;在$HIVE_HOME/conf/hdfs-site.xml中加入&lt;/code&gt;&lt;/p&gt;
&lt;pre name=&quot;code&quot; class=&quot;xml&quot;&gt;
&amp;lt;property&amp;gt;
    &amp;lt;name&amp;gt;hive.hwi.war.file&amp;lt;/name&amp;gt;
    &amp;lt;value&amp;gt;/lib/hive-hwi-0.8.1.war&amp;lt;/value&amp;gt;
    &amp;lt;description&amp;gt;注意上面的地，war换成你自己的包文件名称&amp;lt;/description&amp;gt;
&amp;lt;/property&amp;gt;
&lt;/pre&gt;
</description>
        <pubDate>Sat, 24 Nov 2012 13:01:58 +0000</pubDate>
        <link>/hive_related/</link>
        <guid isPermaLink="true">/hive_related/</guid>
        
        <category>hadoop</category>
        
        <category>hive</category>
        
        
        <category>技术记录</category>
        
      </item>
    
      <item>
        <title>hadoop trails</title>
        <description>&lt;p&gt;最近在捣鼓hadoop相关东东，部门里面需要总结一个hadoop相关的trails，方便后面freshmen加入时可以参考。写了写，可能不对，供新手参考。自己也还是一个新手啊。&lt;/p&gt;
&lt;p&gt;hadoop还是很多值得学习的地方，hadoop建立者Dogg Cutting 也是lucene的作者，现在又是ASF的主席。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;h1&gt;名词解释&lt;/h1&gt;
&lt;p&gt;与hadoop关联的软件、名词非常多，这里列出一些常用的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;hadoop: 一整套分布式存储、计算解决方案&lt;/li&gt;
&lt;li&gt;hdfs: 一套分布式文件系统&lt;/li&gt;
&lt;li&gt;mapreduce: 一套分布式计算框架&lt;/li&gt;
&lt;li&gt;hbase: 基于hdfs的column family 的nosql数据库&lt;/li&gt;
&lt;li&gt;hive: 一套将类似sql的hql转换成mapreduce job的工具&lt;/li&gt;
&lt;li&gt;thrift: 一套用于各种语言间通讯的协议以及实现&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;搭建环境&lt;/h2&gt;
&lt;h3&gt;搭建基本的hadoop环境&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在本地环境搭建伪分布式的hadoop环境，包括基本的hdfs和mapreduce&lt;/li&gt;
&lt;li&gt;在本地环境搭建hive和hbase等关联的环境&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;检验&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;本地能够搭建一个hadoop环境，并且实现以下功能&lt;/li&gt;
&lt;li&gt;将本地文件放入hdfs&lt;/li&gt;
&lt;li&gt;运行一个基于hdfs的mapreduce示例程序&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;使用hdfs&lt;/h2&gt;
&lt;h3&gt;需要知道的知识&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;hadoop文件存放的方式&lt;/li&gt;
&lt;li&gt;hadoop对文件系统操作命令行的使用&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;检验&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;上传文件到hdfs&lt;/li&gt;
&lt;li&gt;从hdfs中获取文件到本地&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;使用mapreduce&lt;/h2&gt;
&lt;h3&gt;需要知道的知识&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;基本的java面向类编程&lt;/li&gt;
&lt;li&gt;mapreduce的过程&lt;/li&gt;
&lt;li&gt;如何自己写一个mapreduce程序&lt;/li&gt;
&lt;li&gt;如何运行mapreduce程序&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;检验&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;知道什么逻辑应该在map端处理，什么逻辑在reduce时处理&lt;/li&gt;
&lt;li&gt;写一个程序统计一个文件中各个单词出现的次数&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;进一步了解hdfs&lt;/h2&gt;
&lt;h3&gt;需要知道的知识&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;hdfs的架构&lt;/li&gt;
&lt;li&gt;namenode和datanode的作用&lt;/li&gt;
&lt;li&gt;hdfs中的block&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;检验&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;描述一个客户端上传文件到hdfs时，各个结点之间的通讯次序。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;进一步了解mapreduce&lt;/h2&gt;
&lt;h3&gt;需要知道的知识&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;数据如何在map和reduce过程传递的&lt;/li&gt;
&lt;li&gt;job是如何分配的&lt;/li&gt;
&lt;li&gt;输入的数据是如何分配给map程序的&lt;/li&gt;
&lt;li&gt;map计算出来的结果是如何组织的，然后传递给reduce的&lt;/li&gt;
&lt;li&gt;一个任务map的个数取决于哪些因素&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;检验&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;描述一个客户端提交了一个mapreduce的任务，hadoop内部各个结点做了哪些动作。&lt;/li&gt;
&lt;li&gt;自定义mapreduce的InputFormat, OutputFormat, Writable&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</description>
        <pubDate>Sat, 24 Nov 2012 12:17:42 +0000</pubDate>
        <link>/hadoop-trails/</link>
        <guid isPermaLink="true">/hadoop-trails/</guid>
        
        <category>hadoop</category>
        
        
        <category>技术记录</category>
        
      </item>
    
      <item>
        <title>在eclipse中调试solr</title>
        <description>&lt;p&gt;最近需要查看搜索执行代码的情况，故需要在eclipse中调试solr，网上出名那篇来自lucid的&lt;a title=&quot;setting up sold in eclipse&quot; href=&quot;http://www.lucidimagination.com/devzone/technical-articles/setting-apache-solr-eclipse&quot; target=&quot;_blank&quot;&gt;《setting up apache solr in eclipse》&lt;/a&gt;，但个人觉得不是很方便。&lt;/p&gt;
&lt;p&gt;自己看了一下，可以使用以下方法：&lt;/p&gt;
&lt;p&gt;1 下载solr的src包，并解压&lt;/p&gt;
&lt;p&gt;2 解压后，在解压后的根目录执行ant eclipse，即生成eclipse需要的项目文件&lt;/p&gt;
&lt;p&gt;打开eclipse，File &amp;gt; Import &amp;gt; Existing Projects into Workspace&lt;/p&gt;
&lt;p&gt;选择刚才解压后的根目录，这时候java build path等都已经设置好了。&lt;/p&gt;
&lt;p&gt;3 Open Type找到StartSolrJetty 这个类，修改main方法里面的setPort参数为默认的8983，以及ContextPath,War&lt;/p&gt;
&lt;p&gt;War为&quot;solr/webapp/web/&quot;&lt;/p&gt;
&lt;p&gt;最后的代码应该是这样的：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Server server = new Server();&lt;/p&gt;
&lt;p&gt;SocketConnector connector = new SocketConnector();&lt;/p&gt;
&lt;p&gt;// Set some timeout options to make debugging easier.&lt;/p&gt;
&lt;p&gt;connector.setMaxIdleTime(1000 * 60 * 60);&lt;/p&gt;
&lt;p&gt;connector.setSoLingerTime(-1);&lt;/p&gt;
&lt;p&gt;connector.setPort(8983);&lt;/p&gt;
&lt;p&gt;server.setConnectors(new Connector[] { connector });&lt;/p&gt;
&lt;p&gt;WebAppContext bb = new WebAppContext();&lt;/p&gt;
&lt;p&gt;bb.setServer(server);&lt;/p&gt;
&lt;p&gt;bb.setContextPath(&quot;/solr&quot;);&lt;/p&gt;
&lt;p&gt;bb.setWar(&quot;solr/webapp/web&quot;);&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;4 设置solr.solr.home，并run&lt;/p&gt;
&lt;p&gt;在run configure中Arguments &amp;gt; VM arguments中写入&lt;/p&gt;
&lt;p&gt;-Dsolr.solr.home=solr/example/solr&lt;/p&gt;
&lt;p&gt;使用solr自带的一个example作为sold配置的根目录，如果你有其他的solr配置目录，设置之即可。&lt;/p&gt;
&lt;p&gt;点击run即可，debug也是一样可以用了。&lt;/p&gt;
</description>
        <pubDate>Sun, 10 Jun 2012 14:43:50 +0000</pubDate>
        <link>/solr_in_eclipse/</link>
        <guid isPermaLink="true">/solr_in_eclipse/</guid>
        
        
        <category>自言自语</category>
        
      </item>
    
      <item>
        <title>swfupload笔记</title>
        <description>&lt;p&gt;很早以前记的，放在草稿箱里，没有发出来，现发出来，因为是笔记，所以看起来可能比较乱。&lt;/p&gt;
&lt;p&gt;swfupload是上传大文件、显示上传进度以及一次上传多个文件的很好选择。但由于其采用了flash做为上传的客户端，带来了以下问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cookie无法和浏览器共享：如果你限制用户登录了后才能上传，那么，用户在浏览器里的cookie你要通过post的形式传过去。&lt;/li&gt;
&lt;li&gt;跨域问题：若swfupload所用的swf文件和上传处理段不在同一域名，便有此跨域问题，解决倒也简单，在上传处理端加个crossdomain.xml即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;crossdomain.xml示例：&lt;/p&gt;
&lt;blockquote&gt;
&lt;pre&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE cross-domain-policy SYSTEM &quot;http://www.adobe.com/xml/dtds/cross-domain-policy.dtd&quot;&amp;gt;
&amp;lt;cross-domain-policy&amp;gt;
    &amp;lt;site-control permitted-cross-domain-policies=&quot;all&quot;/&amp;gt;
    &amp;lt;allow-access-from domain=&quot;*.swfuploadfile.com&quot; /&amp;gt;
    &amp;lt;allow-http-request-headers-from domain=&quot;*&quot; headers=&quot;*&quot; /&amp;gt;
&amp;lt;/cross-domain-policy&amp;gt;&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;p&gt;更让人头疼的是报2038错误（error=-200 message=#2038），这个错误实在折腾人啊。&lt;/p&gt;
&lt;p&gt;先看看adobe官网是怎么说的：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html?filter_flash=cs5&amp;amp;filter_flashplayer=10.2&amp;amp;filter_air=2.6&quot; target=&quot;_blank&quot;&gt;http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html?filter_flash=cs5&amp;amp;filter_flashplayer=10.2&amp;amp;filter_air=2.6&lt;/a&gt;&lt;br /&gt;
里面讲到了ioerror出现的可能&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An input/output error occurs while the player is reading, writing, or transmitting the file.&lt;/li&gt;
&lt;li&gt;The SWF file tries to upload a file to a server that requires authentication (such as a user name and password). During upload, Flash Player or Adobe AIR does not provide a means for users to enter passwords. If a SWF file tries to upload a file to a server that requires authentication, the upload fails.&lt;/li&gt;
&lt;li&gt;The SWF file tries to download a file from a server that requires authentication, within the stand-alone or external player. During download, the stand-alone and external players do not provide a means for users to enter passwords. If a SWF file in these players tries to download a file from a server that requires authentication, the download fails. File download can succeed only in the ActiveX control, browser plug-in players, and the Adobe AIR runtime.&lt;/li&gt;
&lt;li&gt;The value passed to the &lt;code&gt;url&lt;/code&gt; parameter in the &lt;code&gt;upload()&lt;/code&gt; method contains an invalid protocol. Valid protocols are HTTP and HTTPS.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/runtimeErrors.html&quot; target=&quot;_blank&quot;&gt;http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/runtimeErrors.html&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2038&lt;/strong&gt; File I/O Error.This error occurs when an application can't get file size, creation date or modification data using the FileReference API.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;大概意思就是没有办法获得文件信息，另外一方面是由于上传接口需要http验证，无法输入用户名和密码无法所致。&lt;/p&gt;
&lt;p&gt;那么先检查一下上传接口是否有上述问题（使用最原始的上传方式检查），如果上传接口正常，那么需要想想是不是客户端的问题了。有用户说杀毒软件会禁止flash上传，这个我没有实际的验证，但的确遇到过在同一swfupload系统，在有些客户端报2038错，而在其他的地方正常。&lt;/p&gt;
&lt;p&gt;若所有的客户端都出现此问题，那么还是有可能上传接口的问题，我就碰到一例：&lt;/p&gt;
&lt;p&gt;情况如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上传接口前面有一nginx做转发，且这个nginx距离实际处理上传文件的app服务器还有一段距离。&lt;/li&gt;
&lt;li&gt;上传小文件正常，上传大文件会报2038 io error。&lt;/li&gt;
&lt;li&gt;若不使用nginx转发，flash直接往app服务器上传文件，大文件也正常上传。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;去检查nginx的log&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;cat nginx.log  | grep Flash | awk '$12 == 413 {print $0}'&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;发现nginx的响应状态是499，而非正常的200。&lt;/p&gt;
&lt;p&gt;怀疑nginx转发有问题，在客户端上传的同时，在nginx服务器上抓包看看：&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;sudo tcpdump  -vvv -n -A host upload-app and port 80&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;发现nginx转发的request的post数据不全，同时upload-app服务器上给出的响应是 400 bad request。&lt;/p&gt;
&lt;p&gt;至此，初步将原因定为flash player主动断开连接，因为本地的nginx log里面是499，关于499，http协议rfc2616中没有定义，通过相关资料查询可得，499为客户端（flash player）主动断开连接。关于nginx的499可以参考以下文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://forum.nginx.org/read.php?2,213789,213789&quot; target=&quot;_blank&quot;&gt;http://forum.nginx.org/read.php?2,213789,213789&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.ruby-forum.com/topic/137312&quot; target=&quot;_blank&quot;&gt;http://www.ruby-forum.com/topic/137312&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为什么flash会主动断开连接？我也不知。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
</description>
        <pubDate>Sun, 04 Mar 2012 14:23:40 +0000</pubDate>
        <link>/swfupload_tips/</link>
        <guid isPermaLink="true">/swfupload_tips/</guid>
        
        <category>swfupload</category>
        
        
        <category>技术记录</category>
        
      </item>
    
  </channel>
</rss>
