2015年12月28日星期一

Spark 遇到中文乱码问题如何解决?

Spark 遇到中文乱码问题如何解决?

Spark 遇到中文乱码问题如何解决?

  • 问题原因:
    一般是spark平台机器环境编码设置问题

  • 解决方法:

    1. 在spark-default中为executor加上-Dfile.encoding=UTF-8
      spark/conf/spark-defaults.conf
1.spark.executor.extraJavaOptions -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=4 -XX:NewRatio=3 -XX:SurvivorRatio=3 -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationStoppedTime -Dfile.encoding=UTF-8
  1. 在所有涉及到字节转换时,一定要指定编码方式
1.String -> Byte: 
2.string.getBytes("UTF-8")
3.
4.Byte -> String:
5.new String(bytes, "UTF-8")

2015年12月25日星期五

hive命令行使用反射

Untitled
  • HIVE自带反射
1.hive> add jar /home/work/metastore.online/hive/lib/commons-codec-1.3.jar;                                                           
2.Added /home/work/metastore.online/hive/lib/commons-codec-1.3.jar to class path
3.Added resource: /home/work/metastore.online/hive/lib/commons-codec-1.3.jar
4.hive> select reflect("org.apache.commons.codec.binary.Base64","decodeBase64","NGJkYjRhLS1iMTQ2ZjQ5Ni5jb20") from test.dual limit 1;

2015年11月29日星期日

SVN file marked as a binary type 问题处理

http://bigsec.net/one/tool/svn.html

Java7 ForkJoin框架

概述:
http://www.importnew.com/2279.html
example:
http://www.javacodegeeks.com/2013/02/java-7-forkjoin-framework-example.html

读取sequenceFile

http://hadooptutorial.info/reading-and-writing-sequencefile-example/
http://www.programcreek.com/java-api-examples/index.php?api=org.apache.hadoop.io.DataInputBuffer

跨域登录技术


淘宝跨域获取Cookie分析
http://www.oschina.net/question/4873_18517

说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html

jsonp实现跨域读写cookie
http://blog.csdn.net/pangudashu/article/details/19078535

跨域登录技术讨论
http://www.liaoqiqi.com/post/245

Java原子变量

  • 比AtomicLong还高效的LongAdder 源码解析
http://ifeve.com/atomiclong-and-longadder/

2015年11月28日星期六

星巴克不使用两阶段提交

原文: http://www.eaipatterns.com/ramblings/18_starbucks.html
译文:http://blog.csdn.net/linzhiqi07/article/details/8483784?utm_source=jiancool

2015年11月15日星期日

Spark Streaming DirectAPI

为了实现HA,spark Streaming App需要满足三个条件:
  • WAL: write ahead log
  • checkpoint
  • Reliable Receiver
 以上条件可以满足an-least-once语义,同时,WAL的性能消耗较大。对于已经做好数据持久化和安全性的上游系统而言,WAL略显多余(所有数据会被再持久化一次),只需要记录数据的metadata即可.出现Failures时,重新读取数据即可。
 Kafka的DirectAPI提供了一种方案:不使用Receiver,而是直接实现InputDStream,将Kafka中的数据读取为RDD,依靠Spark自身提供的RDD HA保证了输入端的exactly-once语义。同时,因为没有Receiver,所有的数据不会被WAL,性能也更好了。
 备注:DirectKafkaInputDStream读取Kafka中的数据为RDD,按照Kafka的Topic和Partition进行Partition。所有的数据即读即取,也就没有了Active Batches,不需要额外的RDD数据备份。

 KafkaDirectAPI实现要点:
DirectKafkaInputDStream-->{KafkaRDD(partitions) ...}-->Kafka Simple Consumer
依据RDD的容错机制,省去了WAL的性能消耗

 DirectKafkaInputDStream重新设计的CheckPoint需要保存的数据,即Kafka读取的offset。

 当然,对于其他类似的上游系统,也可以设计类似的DirectApi,前提条件是:能够提供和Kafka类似的offset机制,即消息有唯一的ID标识,且ID是顺序的,可以保证重复读取。

2015年11月11日星期三

OLAP简单记

OLAP(On-line Analytical Processing,联机分析处理)是在基于数据仓库多维模型的基础上实现的面向分析的各类操作的集合。
事实表(Fact Table)和维表(Dimension Table)
事实表是用来记录具体事件的,包含了每个事件的具体要素,以及具体发生的事情;维表则是对事实表中事件的要素的描述信息。比如一个事件会包含时间、地点、人物、事件,事实表记录了整个事件的信息,但对时间、地点和人物等要素只记录了一些关键标记,比如事件的主角叫“Michael”,那么Michael到底“长什么样”,就需要到相应的维表里面去查询“Michael”的具体描述信息了。基于事实表和维表就可以构建出多种多维模型,包括星形模型、雪花模型和星座模型。事实表往往是针对一个维度的数据信息,维度表是多个事实表的交叉。

OLAP的基本操作
OLAP的操作是以查询——也就是数据库的SELECT操作为主,但是查询可以很复杂,比如基于关系数据库的查询可以多表关联,可以使用COUNT、SUM、AVG等聚合函数。OLAP正是基于多维模型定义了一些常见的面向分析的操作类型是这些操作显得更加直观。

  OLAP的多维分析操作包括:钻取(Drill-down)、上卷(Roll-up)、切片(Slice)、切块(Dice)以及旋转(Pivot),下面还是以上面的数据立方体为例来逐一解释下:

钻取(Drill-down):在维的不同层次间的变化,从上层降到下一层,或者说是将汇总数据拆分到更细节的数据,比如通过对2010年第二季度的总销售数据进行钻取来查看2010年第二季度4、5、6每个月的消费数据,如上图;当然也可以钻取浙江省来查看杭州市、宁波市、温州市……这些城市的销售数据。
上卷(Roll-up):钻取的逆操作,即从细粒度数据向高层的聚合,如将江苏省、上海市和浙江省的销售数据进行汇总来查看江浙沪地区的销售数据,如上图。
切片(Slice):选择维中特定的值进行分析,比如只选择电子产品的销售数据,或者2010年第二季度的数据。
切块(Dice):选择维中特定区间的数据或者某批特定值进行分析,比如选择2010年第一季度到2010年第二季度的销售数据,或者是电子产品和日用品的销售数据。
旋转(Pivot):即维的位置的互换,就像是二维表的行列转换,如图中通过旋转实现产品维和地域维的互换。

zookeeper学习使用

基于zookeeper的服务发现。
http://www.jdon.com/artichect/zookeeper.html

2015年11月9日星期一

如何序列化一个non serializable的类?

进行Spark开发时,经常会遇到这种问题?如何序列化一个没有实现Serializable接口的类呢?
以下将进行简单说明:Non Serializable记为A。

主要步骤:
0.使用一个外部类Outer将A作为一个成员变量,标记为@transient,且Outer能够通过getter或者其他方式访问A的状态;或者Outer继承A;
1.Outer实现Serializable接口,并且重写readObject和writeObject方法,实现定制化的序列化;
2.Outer在writeObject方法中,将A的状态进行序列化,并且readObject方法中,将A的状态读取出来,对A进行构造。
3.具体实现时,在writeObject方法中,首先调用defaultWriteObject方法,保存所有的non-transient成员,然后保存A的可序列化的状态;在readObject方法中,首先调用defaultReadObject方法,获取所有的non-transient成员,然后读取A的状态。

example:

public class App {

    int quantity;
    int count;

    public int getQuantity() {
        return quantity;
    }

    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }

    public App(int quantity, int count) {
        super();
        this.quantity = quantity;
        this.count = count;
    }

    public int getCount() {
        return count;
    }

    public void setCount(int count) {
        this.count = count;
    }

}

public class UnSerializeItem {

    private App nonSerializableProperty;

    public void setNonSerializableProperty(App nonSerializableProperty) {
        this.nonSerializableProperty = nonSerializableProperty;
    }

    public App getNonSerializableProperty() {
        return nonSerializableProperty;
    }
}

public class OuterItem extends UnSerializeItem implements Serializable{

    private static final long serialVersionUID = 1L;

    private int field;

    public int getField() {
        return field;
    }

    public void setField(int field) {
        this.field = field;
    }

    public OuterItem(int quantity, int count, int field) {
        setNonSerializableProperty(new App(quantity, count));
        this.field = field;
    }

    private void writeObject(java.io.ObjectOutputStream out)
            throws IOException {
        out.defaultWriteObject();
        out.writeInt(super.getNonSerializableProperty().getQuantity());
        out.writeInt(super.getNonSerializableProperty().getCount());
    }

    private void readObject(java.io.ObjectInputStream in)
            throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        super.setNonSerializableProperty(new App(in.readInt(), in.readInt()));
    }
}

2015年10月29日星期四

2015年9月29日星期二

Joda-time介绍

http://www.ibm.com/developerworks/cn/java/j-jodatime.html
http://blog.csdn.net/zeus_9i/article/details/32318771?utm_source=tuicool

lombok介绍

参考:
http://www.blogjava.net/fancydeepin/archive/2012/07/12/lombok.html
http://jnb.ociweb.com/jnb/jnbJan2010.html

lombok 提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码。
前置条件:

  • 安装lombok至eclipse
  • 引入lombok
lombok 注解:
    lombok 提供的注解不多,可以参考官方视频的讲解和官方文档。
    Lombok 注解在线帮助文档:http://projectlombok.org/features/index.    下面介绍几个我常用的 lombok 注解:
        
@Data   :注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法
        
@Setter:注解在属性上;为属性提供 setting 方法
        
@Getter:注解在属性上;为属性提供 getting 方法
        
@Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象
        
@NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
        
@AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
        @NonNull: 注解在属性上,会对setter和构造方法进行NPE判断
        @ToString:注解在类上
        @EqualsAndHashCode
  
@Log4j
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString(callSuper = true, exclude = "id")
@EqualsAndHashCode(exclude = { "id" })
public class Person {

    @NonNull
    private String id;
    private String name;
    private String identity;
}

@Cleanup

The @Cleanup annotation can be used to ensure that allocated resources are released. When a local variable is annotated with @Cleanup, any subsequent code is wrapped in a try/finally block that guarantees that the cleanup method is called at the end of the current scope. By default @Cleanup assumes that the cleanup method is named "close", as with input and output streams. However, a different method name can be provided to the annotation's value parameter. Only cleanup methods which take no parameters are able to be used with this annotation.
  
Lombok annotated code:
public void testCleanUp() {
    try {
        @Cleanup ByteArrayOutputStream baos = new ByteArrayOutputStream();
        baos.write(new byte[] {'Y','e','s'});
        System.out.println(baos.toString());
    } catch (IOException e) {
        e.printStackTrace();
    }
}
Equivalent Java source code:
public void testCleanUp() {
    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            baos.write(new byte[]{'Y', 'e', 's'});
            System.out.println(baos.toString());
        } finally {
            baos.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

@Synchronized

Using the synchronized keyword on a method can result in unfortunate effects, as any developer who has worked on multi-threaded software can attest. The synchronized keyword will lock on the current object (this) in the case of an instance method or on the class object for a static method. This means that there is the potential for code outside of the control of the developer to lock on the same object, resulting in a deadlock. It is generally advisable to instead lock explicitly on a separate object that is dedicated solely to that purpose and not exposed in such a way as to allow unsolicited locking. Project Lombok provides the @Synchronized annotation for that very purpose.
Annotating an instance method with @Synchronized will prompt Lombok to generate a private locking field named $lock on which the method will lock prior to executing. Similarly, annotating a static method in the same way will generate a private static object named $LOCK for the static method to use in an identical fashion. A different locking object can be specified by providing a field name to the annotation's value parameter. When a field name is provided, the developer must define the property as Lombok will not generate it.
Lombok annotated code:
private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");

@Synchronized
public String synchronizedFormat(Date date) {
    return format.format(date);
}
Equivalent Java source code:
private final java.lang.Object $lock = new java.lang.Object[0];
private DateFormat format = new SimpleDateFormat("MM-dd-YYYY");

public String synchronizedFormat(Date date) {
    synchronized ($lock) {
        return format.format(date);
    }
}

@SneakyThrows

@SneakyThrows is probably the Project Lombok annotation with the most detractors, since it is a direct assault on checked exceptions. There is a lot of disagreement with regards to the use of checked exceptions, with a large number of developers holding that they are a failed experiment. These developers will love @SneakyThrows. Those developers on the other side of the checked/unchecked exception fence will most likely view this as hiding potential problems.
Throwing IllegalAccessException would normally generate an "Unhandled exception" error if IllegalAccessException, or some parent class, is not listed in a throws clause:
When annotated with @SneakyThrows, the error goes away.
Screenshot of a method annotated with @SneakyThrows and generating no error in Eclipse.
By default, @SneakyThrows will allow any checked exception to be thrown without declaring in the throws clause. This can be limited to a particular set of exceptions by providing an array of throwable classes ( Class<? extends Throwable>) to the value parameter of the annotation.
Lombok annotated code:
@SneakyThrows
public void testSneakyThrows() {
    throw new IllegalAccessException();
}
Equivalent Java source code:
public void testSneakyThrows() {
    try {
        throw new IllegalAccessException();
    } catch (java.lang.Throwable $ex) {
        throw lombok.Lombok.sneakyThrow($ex);
    }
}
A look at the above code and the signature of Lombok.sneakyThrow(Throwable) would lead most to believe that the exception is being wrapped in aRuntimeException and re-thrown, however this is not the case. The sneakyThrow method will never return normally and will instead throw the provided throwable completely unaltered.

常用Java库

  • 参考:http://www.oschina.net/translate/better-java?from=20150927
  • https://github.com/akullpp/awesome-java
    •   jUnit 4
    •   jMock
    •   AssertJ
    •   Apache Commons
    •   Guava
    •   Gson
    •   Java Tuples
    •   Joda-Time
    •   Lombok
    •   Play framework
    •   SLF4J
    •   jOOQ
    •  Missing Features
    •   Testing

Apache Commons
Apache Commons 项目有一堆实用的库。Apache Commons Pool可以便于实现各种池!
Commons Codec 有许多针对 Base64 和 16 进制字符串的编码/解码方法。你就不要再浪费时间再去重新编写他们了。
Commons Lang 是针对 String 的创建和操作,字符集以及一堆实用工具方法的库。
Commons IO 拥有你可以想象得到的所有文件相关的方法。它有 FileUtils.copyDirectoryFileUtils.writeStringToFileIOUtils.readLines 以及更多的东西。

Guava

Guava 是 Google 的优秀的补充Java所缺的库。几乎很难提交我所喜欢的有关于这个库的所每个功能,但我会试试。
Cache 是获取一个内存缓存的简单方法,可以被用来缓存网络访问,磁盘访问,记忆函数或者任何实在的数据。只要实现一个 CacheBuilder 就能告诉 Guava 如何去构建你的缓存,一切尽在你的掌握之中 !
Immutable 集合。有一堆这样东西 : ImmutableMap,ImmutableList, 或者如果那是你的风格的话,就还有 ImmutableSortedMultiSet .
我也喜欢用 Guava 的方式编写不可变的集合:
?
1
2
3
4
5
// Instead of
final Map<String, Widget> map = new HashMap<String, Widget>();
// You can use
final Map<String, Widget> map = Maps.newHashMap();
还有针对 ListsMapsSets 以及更多集合的静态类。 他们更清晰和可读。
如果你还在 Java 6 或者 7 的坑里面, 你可以使用 Collections2 类, 它拥有像 filter 和 transform 这样的方法. 能让你在没有 Java 8 对流的支持下写出流畅的代码。
Guava 也有一些简单的东西, 比如 Joiner 能用分隔符将字符串连接起来,以及一个通过忽略它们来 处理中断的类.

Gson

Google的Gson 库是一个简单快速的JSON转换库。像下面这样运作:
?
1
2
3
final Gson gson = new Gson();
final String json = gson.toJson(fooWidget);
final FooWidget newFooWidget = gson.fromJson(json, FooWidget.class);
相当简单且令人愉悦。Gson用户手册 有许多的示例。

Java Tuples

Java经常令我头疼的一点就是他的标准库里面并没有内置元组。幸运的是, Java tuples 项目解决了这个问题。
它易于使用而且表现很棒:
?
1
2
3
Pair<String, Integer> func(String input) {
    // something...
    return Pair.with(stringResult, intResult);}

Joda-Time

Joda-Time 是我所使用过的最棒的时间库. 简答,直接,易于测试. 夫复何求?
所以你只要在如果没有使用Java8时使用这个库,因为Java8有了新的 日期时间 库。

Lombok

Lombok 是一个有趣的库。它能通过注解让你减少 Java 所严重遭受的样板式代码。
想要为你的类变量加入设置器和获取器? 简单:
?
1
2
public class Foo {
    @Getter @Setter private int var;}
现在你可以这样做:
?
1
final Foo foo = new Foo();foo.setVar(5);
还有 更多的东西。我还没有将 Lombok 用于生产环境,但我迫不及待的想要这么做了。

Play framework

好的选择 Jersey 或者 Spark
在Java中实现 RESTful web 服务又两个主要的阵营 : JAX-RS 和其余一切。
JAX-RS 是传统的方式。你可以使用诸如Jersey之类的东西来将注解结合接口和实现来组织 web 服务。这里有意思的是你可以简单的从接口类创建出客户端。
Play framework 是 JVM 的 web服务的一个异类:你会有一个路由文件,然后你要编写在这些路由中被引用的类。它实际上是一个完整的 MVC 框架, 但是你可以简单地只把他用于 REST web 服务。
它在 Java 和 Scala 上都能用。它稍有偏向 Scala 优先,不过在Java中也还好.
如果你用过Python中向Flash这样的微型框架, 你就能熟悉 Spark。它在 Java 8 上能运行得很好。

SLF4J

有许多Java日志的解决方案。我喜欢的就是 SLF4J 因为它的极度的可插入性,并且可以同时结合来自不同日志框架的日志. 有没有过一个使用了 java.util.logging, JCL, 以及 log4j 的古怪项目? SLF4J 为你而生。
两页篇幅的操作手册 就是你入门所需要的。

jOOQ

我不想换重量级的 ORM 框架,因为我喜欢 SQL。因此我写了许多 JDBC 模板, 而这样就有点难以维护。 jOOQ 是一个更好的解决方案。
他能让你用 Java 以一种更加类型安全的方式编写SQL:
?
1
2
3
4
5
6
7
8
9
// Typesafely execute the SQL statement directly with jOOQ
Result<Record3<String, String, String>> result = 
create.select(BOOK.TITLE, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)
    .from(BOOK)
    .join(AUTHOR)
    .on(BOOK.AUTHOR_ID.equal(AUTHOR.ID))
    .where(BOOK.PUBLISHED_IN.equal(1948))
    .fetch();
使用这个和 DAO 模式, 你可以使得访问数据库变得轻而易举。

测试

测试对于你的软件至关重要。这些包能使得测试更简单。

jUnit 4

jUnit 不需要介绍了。它是Java中单元测试的标准工具.
而你可能不会发挥 jUnit 的全部潜能。jUnit 支持 参数化测试,,让你不用编写过多样板代码的 规则,随机测试特定代码的 理论, 以及 假设

jMock

如果依赖注入那块你弄好了的话,这时候它就能发挥点作用了 : 模拟那些有副作用的代码 (比如同一个REST服务器进行交互) 并且仍然可以对调用它的代码进行断言。
jMock 是标准的Java模拟工具。它看起来像这样:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class FooWidgetTest {
    private Mockery context = new Mockery();
    @Test
    public void basicTest() {
        final FooWidgetDependency dep = context.mock(FooWidgetDependency.class);
        context.checking(new Expectations() {{
            oneOf(dep).call(with(any(String.class)));
            atLeast(0).of(dep).optionalCall();
        }});
        final FooWidget foo = new FooWidget(dep);
        Assert.assertTrue(foo.doThing());
        context.assertIsSatisfied();
    }}
这里通过 jMock 设置了一个 FooWidgetDependency,然后加入了一个预期( expectation)。我们预期 dep 的 call 方法会使用某个字符串被调用一次并且 dep 的 optionalCall 方法会被调用0到多次。
如果你要一次又一次设置相同的依赖,你可能应该将那些放到一个 测试夹具(est fixture)中,并将 assertIsSatisfied 放到一个 @After 夹具中。

AssertJ

你曾经用 jUnit 这样做过吗?
?
1
2
3
4
5
final List<String> result = some.testMethod();
assertEquals(4, result.size());
assertTrue(result.contains("some result"));
assertTrue(result.contains("some other result"));
assertFalse(result.contains("shouldn't be here"));
这都是烦人的样板代码。 AssertJ 会把这些都干掉。你可以将同样的代码转换成这样:
?
1
2
3
assertThat(some.testMethod()).hasSize(4)
                             .contains("some result""some other result")
                             .doesNotContain("shouldn't be here");
这样流畅的接口让你的测试更加可读. 夫复何求?