Quantcast
Channel: PayMoon贝明实验室
Viewing all 130 articles
Browse latest View live

[Spring Security 4][原理]源码与启动原理/工作模式

$
0
0
关于spring security的加载方式,其很多还是依赖spring容器,所以我们这里只关注 Spring Security的获取加载模式。 本文http://www.paymoon.com:8001/index.php/2016/12/07/how-do-ss4-start-and-work/ 如果转载请联系i@paymoon.com Spring-Security的切入点为DelegatingFilterProxy web.xml配置如下<实战会讲> [crayon-584d49a298adf482938680/] 我们从DelegatingFilterProxy开始到具体工作过程
这个filter本身并不处理具体的请求,它其实是一个filter chain,它内部包含了一个由多个spring security提供的filter的list,它负责把请求委派给list中的每一个filter进行处理。
他是spring的web包下的class, 继承了

GenericFilterBean,

而GenericFilterBean implements Filter

所以 DelegatingFilterProxy本质上是一个filter,并且会执行dofilter, 由于本身他就是代理,他会依赖演注入的filter, 是哪个呢?
他的变量:

private volatile Filter delegate;

请看他的dofilter方法,

[crayon-584d49a298ae9606368754/]
这个springSecurityFilterChain的变量delegate来源都是spring security包提供的类,如前文所述,这些filter实例都是spring的inner bean,是由spring隐式地初始化并置于容器中管理的。
当然,如果想指定的话,我们是可以指定加载哪些filter和顺序的,就在配置文件applicationContext-security.xml
[crayon-584d49a298af0880536879/]
这个filter就会走到我们之前说到ss4实现权限流程中的UsernamePasswordAuthenticationFilter和FilterSecurityInterceptor
示例的代码中,因为我写了自定义的myAuthenticationFilter<继承了UsernamePasswordAuthenticationFilter>
和myFilter<继承了FilterSecurityInterceptor>
两者区别:
UsernamePasswordAuthenticationFilter:该filter用于用户初次登录时验证用户身份(authentication)。该filter只在初次认证时存在,一旦认证通过将会从 filter chain中移除。
 
FilterSecurityInterceptor:当用户登入成功之后,每次发送请求都会使用该filter检查用户是否已经通过了认证。如果通过了认证,就放行,否则转向登录页面。
两个filter的差别在于: 第一个负责初次登入时的用户检查,这个检查需要根据用户提供的用户名和密码去数据库核对,若存在,将相关信息封装在一个Authentication对象中。这个filter可以说是处理初次登录时的authentication工作。而第二个filter则不需要像每个filter每次都去查询数据库,它只需要从 security context中查看当前请求用户对应的Authentication 对象是否已经存在就可以了,这个filter处理的是登入成功之后的authentication工作。这个filter是需要拦截每次请求的。

本文http://www.paymoon.com:8001/index.php/2016/12/07/how-do-ss4-start-and-work/ 如果转载请联系i@paymoon.com

相关文章:
http://www.paymoon.com:8001/index.php/2016/12/07/how-ss4-apply-the-permission/

[Spring Security 4][原理]几个相关重要的几个class

$
0
0
我们知道根据前文Spring Security实现权限的原理,SS4分为授权和认证,并且根据上文SS4启动原理可知,这两块的主要功能的相关class为 本文http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/ 如果转载请联系i@paymoon.com

一 、认证

UsernamePasswordAuthenticationFilter.attemptAuthentication(req, res) 用户的参数拦截最终实现者

UserDetailsService .loadUserByUsername(String username) 系统用户信息的最终实现者

上述两class分别为认证过程中一个用户的信息拦截,一个从系统中拿用户。

SimpleUrlAuthenticationSuccessHandler.onAuthenticationSuccess(req, res)

AuthenticationFailureHandler.onAuthenticationFailure(req, res)

上述两class分别为认证成功和失败后的跳转过程。

所以如果想自定义,继承他们,重写相关方法,然后在xml里面做下配置即可。

配置如下:

[crayon-584d49a2984ea900042627/] [crayon-584d49a2984f5773134295/]

二、授权

仍然根据Spring Security实现权限的原理,我们可知在授权中起重要class为:

AbstractSecurityInterceptor.doFilter(req, res): 拦截url并走到授权的filter

根据其类中的成员变量,可知还有:

authenticationManager(默认实现是UserDetailService),见认证第二部分代码,这里是提供系统用户信息。

securityMetadataSource (默认实现是FilterInvocationSecurityMetadataSource),提供url的角色

accessDecisionManager(默认实现是AccessDecisionManager.decide),对上两个类中用户角色和url角色进行比对,如果角色符合,则向下走,否则抛出AccessDeniedException

配置如下:

[crayon-584d49a2984fc203251749/]

所以这就很明显了,当系统有自定义需求时,(如我们的用户信息不能直接配置在xml里面,也有可能没有数据源,只有接口的时候,我们就需要重继承authenticationManager类[有文章写ss4的第四种用法为重改这些class,我强烈建议继承之]),需要实现这三个class(authenticationManager我们已经在认证实现)

说下一般自定义场景

自定义认证

继承UsernamePasswordAuthenticationFilter的意义

可以看这个类的属性可知,当我们获取request里面的用户,密码不是username,password时(Spring Security默认是这两个),我们可以自定义之

当我们有密码加密,需要在之后做校验时,我们也需要在这里进行对密码进行加密。

本文http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/ 如果转载请联系i@paymoon.com

继承authenticationManager的意义

刚刚也说过,如我们的用户信息不能直接配置在xml里面,也有可能没有数据源,只有接口的时候,我们就需要重继承authenticationManager类

继承认证通过的跳转类

SimpleUrlAuthenticationSuccessHandler.onAuthenticationSuccess(req, res)

AuthenticationFailureHandler.onAuthenticationFailure(req, res)

目的在于我们login后,可能不想返回到某个jsp,或者此jsp我们根本不在本项目中,或根本不在一个机器中,我们只能返回统一的标准json接口,这时候就要用这两个class重写跳转,方便我们返回接口,跳转时可能还会涉及到跨域,到实战会讲。

自定义授权

继承AbstractSecurityInterceptor

有人会想这就是一个filter, 我继承它干嘛呢,其实我们看到Spring Security实现的多细致多深,可是别忘了,SS4只能做到URL的控制粒度,如果我们想做数据粒度的控制,比如leader可以看到整个team的数据,当前team player只能看到他自己的数据,我们怎么做呢,我们需要自己写实现,在url的授权通过后,走我们自己的实现,这时候继承这个filter就非常重要了。

继承authenticationManager,这个就不用再说了,用户信息和角色,btw一般在比对角色的时候,都会从redis里面拿数据

继承securityMetadataSource,这个是url的角色,当我们要汇全当前url所有角色时,还有可能是我们的角色有自己的继承关系,如admin是manager的上级,我们需要继承这个,写自己的实现,以方便拿到所有的角色。

继承AccessDecisionManager,这个类的存在意义就不用再多说,比对角色是否符合就在这里决定,符合向后走[有可能就会走到我们刚说的数据权限],不符合throw exception,

[crayon-584d49a298505470128246/] 其实这是一个总的比较类,在Spring Security里面,对于角色匹配,还有投票机制,即如果全部通过投票,则有权访问,也有一票决定权,不过因为那种细的粒度一般难以遇到,所以这里先不表。

Spring Security4 实战:深度定制实用+可配置的安全方案

$
0
0

大家好,今天晚上很荣幸和大家一起,分享和探讨Spring Security的入门,使用,原理和相关问题。

我先做下自我介绍,花名龙遥,做Java有四年了,在第三方支付做的时间长一点,对分步式计算,存储有一点研究。

Spring Security 4 是我们上个月在做一个新产品中用到的,用的时间并不长,我就把我用到的功能,相关原理分享给大家,如果有问题希望和大家一起探讨。

我先给大家发一下分享的目录,如下:

、目标

[概念]了解基于资源的权限管理方式、SS4如何实现权限的原理

[模型]掌握权限数据模型

[基本功能]实现认证、授权。

[基本功能]基于URL/操作 实现资源权限管理

[进阶]密码加密处理

[进阶]CSRF攻击方式/防御/使用

[进阶]前端与后端的脱离

[进阶]token的存储redis集中式方法

[进阶]跨域的处理

[高级]自定义:与实际的企业web项目整合开发的方法

[进阶]定制user provider

自定义 认证的过滤器

自定义认证过滤器【authenticationSuccessHandlerauthenticationFailureHandler

自定义filter,包含 authenticationManager,accessDecisionManager,securityMetadataSource

[高级]分步式:远程调用/Jar包管理

二、相关原理

1[权限]权限的原理

  1.1 [3w1h]Spring security 4

    1) what SSH4是什么

    2 )who [使用对象]谁需要使用

需要对资源保护的系统/模块

    3) why Spring security 4 '

http://www.paymoon.com:8001/index.php/2016/12/07/ss4why-are-spring-security-4/

    4 )How 原理是怎样,怎么使用,使用到哪种程度?

2[用户层面]用户认证与授权过程

在实战前,我们先简单了解下在Spring Security中的认证与授权过程,

3[SS4层面]SS4是如何把权限实现的原理

4[SS4层面]源码与启动原理/工作模式

5[自定义]相关重要的几个class

三、实战

二个项目

1第一个最快生效的案例

2第二个支持自定义的上线的案例

四、问题

1、使用问题

从只知道一个名词到上线使用

如何从只知道概念到第一个案例

2、使用问题

失败跳转导致csrf没发现

如何发现dao里做验证

url跳转,做了一个controller

controller里获取用户信息

跨域问题两个方案,servlet归本溯源

3、从3迁移到4的问题

4、扩展问题【定制与分步式


浏览顺序,可以跳过目标,从二原理到三的实战,实战中会穿插目标的各种实现

[Spring Security 4][实战]第一个最快生效的案例

$
0
0
本文http://www.paymoon.com:8001/index.php/2016/12/08/spring-security-4-in-action-the-first-demo/ 如果转载请联系i@paymoon.com 我已经把[权限]权限的原理[SS4层面]SS4是如何把权限实现的原理掰的相当明白了,下面我就开始说案例了,先说第一个案例。

第一个案例,使用的是SS3不过不耽误我们认识Spring Security认证,授权的实现过程,我已经放在了GitHub上。

github地址https://github.com/stevenlii/spring_security_example

环境依赖:

Eclipse/Spring tool Suite

Maven

Tomcat

first demo

搭建过程, Eclipse中新建常规的Maven Web项目

pom.xml添加依赖

[crayon-584d49a297e01037738368/]

web.xml配置

[crayon-584d49a297e0c236719583/] 我也经常这样写: [crayon-584d49a297e12707637979/]

filter拦截,[SS4层面]源码与启动原理/工作模式中讲过

[crayon-584d49a297e17714181550/]

一切基于xml配置,applicationContext-security就是SS4中主要的配置,

我们先配置一个数据全面在xml里面的案例

[crayon-584d49a297e1d278773285/]

这个是最简单的配置,数据都在xml里面,所有http相关的基于url的配置全部都在http里面,配置包含两个,一个是<http>标签里面关于intercept-url 的资源url和角色描述的权限,一个是<authentication-manager>里面的用户和角色。

本文http://www.paymoon.com:8001/index.php/2016/12/08/spring-security-4-in-action-the-first-demo/ 如果转载请联系i@paymoon.com

默认只需完成以上两个配置,启动服务器

用浏览器打开这个Web应用的任意页面,都会跳转到一个登录页,这个登录页面是Spring Security自动生成的。

1133

在登录页面输入错误的用户名密码,就会登录失败并有提示。输入正确的用户名密码,则登录成功,就可以进入Web应用的页面。

这是最简单版本的实现。

本文http://www.paymoon.com:8001/index.php/2016/12/08/spring-security-4-in-action-the-first-demo/ 如果转载请联系i@paymoon.com

但是我们马上发现了两个问题,一是login页面,样式我们会想自定义,二是用户信息,我们不能配置在xml里面了。

以及,

如果我们的其它服务,是模块化的,或者说是分步式设计的,可能你想用的页面,根本就没在这个项目下,甚至都不在一个机器上,这时候调不了login.jsp了,怎么办?

登录的用户名不是username/password怎么办?

我们如何定义url级别和数据权限?

这时候请关注第二个案例。

本文http://www.paymoon.com:8001/index.php/2016/12/08/spring-security-4-in-action-the-first-demo/ 如果转载请联系i@paymoon.com

[Spring Security 4][实战]第二个定制化的案例

$
0
0
第一个案例在此 然后在说这个案例时,我们还是依赖[权限]权限的原理[SS4层面]SS4是如何把权限实现的原理,下面先说下问题 一是login页面,样式我们会想自定义,二是用户信息,我们不能配置在xml里面了。 说下这两个问题解决: login/logout页面配置 仍然是在applicationContext-security里面配置 <http>form-login配置login, [crayon-584d49a296b16763647526/] 配置完后我们不希望login.jsp需要权限于是 [crayon-584d49a296b23301286878/]

想省事就这样配置:

[crayon-584d49a296b29623092543/]

这两个效果不太一样,access是能获取用户信息的,security则就相反了,用户信息会被忽略,这两个配置很有用,下面会讲到。

完整配置如下:

[crayon-584d49a296b2e092233967/]

相关页面代码

login.jsp [crayon-584d49a296b34624271130/] [crayon-584d49a296b39219481130/] 两个方法都是post请求,大家会注意到一个地方: <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" /> 这个就是CSRF了,与SS3不同,他是SS4里面默认都会开启的,为了安全,防止恶意的CSRF攻击,Spring Security需要校验form表单中的hidden域提交的内容。 关于CSRF可以插播一下,他是什么东东 [Spring Security 4]CSRF攻击方式/防御/使用 – PayMoon贝明实验室 www.paymoon.com:8001/index.php/2016/12/08/csrf-attack-and-defence/

当然,因为开启了CSRF,需要在每次提交数据里面都加上CSRF,如果你有别的安全措施,或者不想加,可以在xml里面不用的,方法如下:

<csrf disabled="true"/>

否则如果不加hidden这一段会报错

登录的问题好像解决了,但是,如果我们的其它服务,是模块化的,或者说是分步式设计的,可能你想用的页面,根本就没在这个项目下,甚至都不在一个机器上,这时候调不了login.jsp了,怎么办?

登录的用户名不是username/password怎么办

那我们就只能提供服务了,提供能够返回类似json这种数据格式的服务,也就是前端调用我们提供的login服务,我们返回成功与否的判断+数据。

这就要自定义认证过程了

在重写之前

我们需要重新看一下SS4的认证过程,找到其登录过程和跳转机制

参考如下

[SS4层面]SS4是如何把权限实现的原理

[Spring Security 4][原理]几个相关重要的几个class – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/

可知我们需要继承实现UsernamePasswordAuthenticationFilter

先上一下实现配置过程

[crayon-584d49a296b42400859067/] 我们在把filter加在login的时候用,需要用到

<b:property name="filterProcessesUrl" value="/login" />

<custom-filter ref="myAuthenticationFilter" position="FORM_LOGIN_FILTER" />

这样我们就可以在自定义handler里面做自定义跳转了

那么怎么跳转呢

还记得Successhanlder吗

[crayon-584d49a296b4a181097493/]

需要把我们的数据,序列化为json,就可以了。

问题来了,

因为这里面没有springmvc,我们怎么写数据呢,回本溯源,直接使用servletprint方法即可。

实现这个之后,只要通过项目的login就可以走进登录,并且校验通过或者失败后,就会返回我们预期的json

关于跨域的解决办法,我有写过博客,大家可以参考

JAVA WEB支持CORS 跨域访问 – PayMoon贝明实验室

http://www.paymoon.com:8001/index.php/2016/05/30/java-web-support-cors-visit/

跨域问题的解决办法Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response. – PayMoon贝明实验室

http://www.paymoon.com:8001/index.php/2016/11/23/request-header-field-content-type-is-not-allowed-by-access-control-allow-headers-in-preflight-response/

再接着这个说一句,如果跨域需要自己造轮子,或者容器tomcat版本低还不支持,可以自己写filter解决跨域问题。

print方法如下,Access-Control-Allow-Origin是域名过滤,下面的一些参数是支持的header, Method等

[crayon-584d49a296b53801042959/]

这样登陆的问题,从界面到分布式我们就解决了。

该用户来源的问题了:

我们如何自定义数据来源

如:从数据库中获取

刚刚说到,用户来源问题是provider里面提供的,可以看标签,那我们就可以在这里面自定义provider,我们先说通过数据库的方式

先看一下之前xml的方式

[crayon-584d49a296b59110946908/]

user-service就是我们说的provider,如果我们想自定义,

需要先在配置文件里面配置好数据源,然后通过sql的方式,加载数据,

配置好数据源

[crayon-584d49a296b5f382560242/]

数据模型这里也提供了一份,可以看github上,模型就是按照我们之前介绍的权限模型,有初始化的数据,

配置文件sql写法

[crayon-584d49a296b65948970682/]

在这种情况下我们看下密码加密方式

密码加密有可逆和不可逆,很多,这里不是重点,不过提一下,spring4最近使用bcrpt的多,和传统md5hash加密不同,他的执行慢,解密成本大,所以用时间换了安全。

上面代码注释的部分,就是加密的部分,是md5的salt加密方式

如果我们想要的数据,根本不在可获知的数据源上,我们只有接口,或者说,我们用户的提供方式,想自己写,那怎么办呢

自定义

要了解自定义,就得知道。在哪里进行认证的 dao

根据

[SS4层面]SS4是如何把权限实现的原理

[Spring Security 4][原理]几个相关重要的几个class – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/

所以我们继承实现UserDetailsService类就可以了

从父类得知,在这个类里面我们把用户提取出来,并且也提供出来角色,这个后面会用到以及是否锁定,账号是否过期等

从这个类和刚刚的UsernamePasswordAuthenticationFilter类,我们可以得知,密码加密的方法不在配置,而是在程序里面做就行了,这样也方便了我们自定义密码加密。

从这里面获取的用户,我们可以生成用户token,然后存储在集中式的缓存服务器上,保证用户的单点登录。

单点的话以后更新..

这就解决了用户认证,分布式,密码加密等的诸多过程

然后就是授权过程。

授权过程

我们的用户已经有了provider,所以我们就只有过滤出资源的角色,然后和用户的角色进行比对,通过就放行即可

相关的实现类,仍然是根据

[SS4层面]SS4是如何把权限实现的原理

[Spring Security 4][原理]几个相关重要的几个class – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/07/spring-security-4-principle-some-important-class/

所以我们继承实现相关url的角色实现和角色比对类就可以了

[Spring Security 4]CSRF攻击方式/防御/使用

$
0
0

CSRFCross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF

CSRF可以做什么?

你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求

CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。

1121

怎么防御

CSRF的原理其实它完全是以用户的身份去执行,而应用程序和浏览器很难去判断这是CSRF攻击还是合法请求。 

那么,防御方法也就是针对这个来设计了。

主要有以下几种方法,简单讲一下:

  • 使用POST方式替代GET
  • 检验HTTP Referer
  • 使用验证码
  • 使用token

检验HTTP Referer

通过检查请求页面的来源,识别从站外发起的请求,也就能防御CSRF了。

使用验证码

每次用户提交内容时,要求其在表单中填写验证码,提交后对其进行检测。 

验证码机制是:服务器生成一个验证码,发送给客户端,以图片形式显示。然后客户填写后,发回服务器,对比验证。

使用token

CSRF能成功的一个重要原因是:攻击者能预知和伪造请求中的关键字段,因此,在请求中放入攻击者不能伪造的信息就能防御CSRF。 

token就是在请求中加入一个随机参数token,服务器进行验证。

SS4的CSRF防御实现

个人猜测SS4的CSRF是通过POST+Token的方式走的,即把token随机生成,然后hidden传输,具体机制知道的朋友也可以探讨下

解决项目的jar和tomcat的jar包冲突

$
0
0
在一个maven项目中,如果存在编译需要而发布不需要的jar包,可以用scope标签,值设为provided。如下: <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.1</version> <scope>provided</scope> <classifier /> </dependency> scope的其他参数如下:
  • compile 默认的scope,表示 dependency 都可以在生命周期中使用。而且,这些dependencies 会传递到依赖的项目中。适用于所有阶段,会随着项目一起发布
  • provided 跟compile相似,但是表明了dependency 由JDK或者容器提供,例如Servlet AP和一些Java EE APIs。这个scope 只能作用在编译和测试时,同时没有传递性。
  • runtime 表示dependency不作用在编译时,但会作用在运行和测试时,如JDBC驱动,适用运行和测试阶段。
  • test 表示dependency作用在测试时,不作用在运行时。 只在测试时使用,用于编译和运行测试代码。不会随项目发布。
  • system 跟provided 相似,但是在系统中要以外部JAR包的形式提供,maven不会在repository查找它。
所以冲突时,只要 [crayon-5851569002e1e694033800/] 即可  

微服务系统中的四种认证策略

$
0
0
软件安全本身就是个很复杂的问题,由于微服务系统中的每个服务都要处理安全问题,所以在微服务场景下会更复杂。David Borsos在最近的伦敦微服务大会上作了相关内容的演讲,并评估了四种面向微服务系统的身份验证方案。 在传统的单体架构中,单个服务保存所有的用户数据,可以校验用户,并在认证成功后创建HTTP会话。在微服务架构中,用户是在和服务集合交互,每个服务都有可能需要知道请求的用户是谁。一种朴素的解决方案是在微服务系统中应用与单体系统中相同的模式,但是问题就在于如何让所有的服务访问用户的数据。解决这个问题大致两个思路:若使用共享用户数据库时,更新数据库表会成为一个难题,因为所有服务必须同时升级以便能够对接修改后的表结构;若将相同的数据分发给所有服务时,当某个用户已经被认证,如何让每个服务知晓这个状态是一个问题。 Borsos指出,单点登录(SSO)方案可能看起来是一个好主意,但这意味着每个面向用户的服务都必须与认证服务交互,这会产生大量非常琐碎的网络流量,同时这个方案实现起来也相当复杂 。 在其他方面,选择SSO方案安全性会很好,用户登录状态是不透明的,可防止攻击者从状态中推断任何有用的信息。 分布式会话方案,原理主要是将关于用户认证的信息存储在共享存储中,且通常由用户会话作为key来实现的简单分布式哈希映射。 当用户访问微服务时,用户数据可以从共享存储中获取。 该解决方案的另一个优点是用户登录状态是不透明的。 当使用分布式数据库时,它也是一个高度可用且可扩展的解决方案。 这种方案的缺点在于共享存储需要一定保护机制,因此需要通过安全链接来访问,这时解决方案的实现就通常具有相当高的复杂性了。 客户端令牌方案, 此令牌在客户端生成,由身份验证服务进行签名,并且必须包含足够的信息,以便可以在所有微服务中建立用户身份。 令牌会附加到每个请求上,为微服务提供用户身份验证。 这种解决方案的安全性相对较好,但身份验证注销是一个大问题, 缓解这种情况的方法可以使用短期令牌和频繁检查认证服务等。 对于客户端令牌的编码方案,Borsos更喜欢使用JSON Web Tokens(JWT),它足够简单且库支持程度也比较好。 客户端令牌与API网关结合,这个方案意味着所有请求都通过网关,从而有效地隐藏了微服务。 在请求时,网关将原始用户令牌转换为内部会话ID令牌。 在这种情况下,注销就不是问题,因为网关可以在注销时撤销用户的令牌。 这种方案虽然库支持程度比较好,但实现起来还是可能很复杂。 Borsos建议使用客户端令牌(使用JWT)和API网关结合的方案,因为这个方案通常使用起来比较容易,且性能也不错。 SSO方案虽然能满足需求,但他认为还是应该避免使用。若分布式会话方案所需要的相关技术已经应用在你的场景上,那么这个方案也是比较有趣的。他同时强调在选择解决方案时应着重考虑注销的重要性。 Reference https://www.infoq.com/news/2016/12/microservices-authentication

[翻译]Spark In Action

$
0
0
前言 这是一个Spark In Action的翻译系列,书名信息:Spark In Action 关注:http://www.paymoon.com:8001/index.php/2016/12/27/spark-in-action-forhead/ qq1111 qq222222 目录: 第一部分 开篇首要 Spark 介绍 Spark 组件 Spark 应用编程 Spark API 深度使用 第二部分 Spark 家族 使用Spark SQL 查询 使用Spark Streaming 获取数据 使用Spark MLib使程序智能 机器学习:分类和聚类 使用Spark GraphX 第三部分 Spark OPS 运行Spark 单机运行Spark 在YARN 和 Mesos上运行Spark 第四部分 综合应用 案例研究:实时仪表板 在Spark上使用H2O 深度学习

[翻译][Spark In Action]Spark 实战 开篇首要

$
0
0
我们从这本书开始介绍Apache Spark及其丰富的API。了解第1部分中的信息对于编写高质量的Spark程序非常重要,并且是本书其余部分的良好基础。 第1章大致描述了Spark的主要特性,并将它们与Hadoop的MapReduce和Hadoop生态系统中的其他工具进行了比较。它还包括我们为您准备的spark-in-action虚拟机的说明,您可以使用它来运行书中的示例。 第2章进一步探讨VM,教你如何使用Spark的命令行界面(spark-shell),并使用几个例子来解释弹性分布式数据集(RDDs) - Spark中的中心抽象。 在第3章中,您将学习如何将Eclipse设置为编写独立的Spark应用程序。然后你将编写一个这样的应用程序来分析GitHub日志并通过将它提交到Spark集群来执行应用程序。 第4章更详细地探讨了Spark核心API。具体来说,它展示了如何使用键值对,并解释了Spark中数据分区和混排的工作原理。它还教你如何分组,排序和连接数据,以及如何使用累加器和广播变量。

[翻译][Spark In Action][Spark 实战 ]Apache Spark 介绍

$
0
0

本章涵盖

Spark带来了什么

Spark组件 Spark程序流 Spark生态系统 下载并启动spark-in-action虚拟机

Apache Spark是一个快速,通用的分布式计算平台。听起来像市场宣传,然而这确实是最适合他的标签。

Apache Spark真的给大数据空间带来了革命。 Spark可以有效地利用内存,并且可以执行等效作业比Hadoop的MapReduce快10到100倍。除此之外,Spark的创建者设法抽象出一个事实,即你正在处理一组机器,而是给你一组基于集合的API。使用Spark的集合感觉像使用本地Scala,Java或Python集合,但Spark的集合引用分布在许多节点上的数据。这些集合的操作被转换成复杂的并行程序,而用户不必知道事实,这是一个真正强大的概念。

在本章中,我们首先阐述了Spark的主要功能,并将Spark与其自然的前身:Hadoop的MapReduce进行比较。

然后,我们简要探讨Hadoop的生态系统 - 一个与Hadoop一起用于大数据操作的工具和语言的集合,以了解Spark如何适应。

我们简要概述Spark的组件,并向您展示典型的Spark程序如何使用简单的“Hello World”示例。

最后,我们帮助您下载并设置我们为在书中运行示例而准备的spark-in-action虚拟机。

我们已经尽最大努力为Spark架构,其组件,运行时环境和API编写了全面的指南,同时提供了具体的示例和现实案例研究。通过阅读本书,更重要的是,通过筛选示例,您将获得编写自己的高质量Spark程序和管理Spark应用程序所需的知识和技能。

[翻译][Spark In Action][Spark 实战 ]1.1 Spark是什么

$
0
0
1.1  Spark 是什么 Apache Spark 是一种令人兴奋的新技术,它迅速取代Hadoop 的MapReduce 作为首选大数据处理平台。 Hadoop 是一个开源的,分布式的Java 计算框架,由Hadoop 分布式文件系统(HDFS)和MapReduce 的执行引擎组成。 Spark 类似于Hadoop,它是一个分布式通用计算平台。但Spark 的独特设计,允许在内存中保存大量的数据,提供了巨大的性能改进。 Spark 程序的速度可以比MapReduce 快100倍。 Spark 最初是在Berkeley 的AMPLab 由Matei Zaharia 构思的,他与他的导师Ion Stoica,以及Reynold Xin,Patrick Wendell,Andy Konwinski 和Ali Ghodsi 一起创办了Databricks。Spark是开源的,Databricks是Apache Spark 的主要力量,贡献了Spark 的75%以上的代码。它还提供Databricks Cloud,一种基于Apache Spark 的大数据分析的商业产品。 通过使用Spark 的优雅的API和运行时架构,您可以以类似于编写本地方式的方式编写分布式程序。 Spark的集合抽象出了这样一个事实,即它们有可能引用分布在大量节点上的数据。 Spark 还允许您使用函数编程方法,这是与数据处理任务完美匹配的。 通过支持Python,Java,Scala和最近的R,Spark对大量用户开放:传统上支持Python和R的科学社区,仍然广泛的Java社区,以及使用越来越多流行的Scala,它提供了在Java虚拟机(JVM)上的功能编程。 最后,Spark在单一框架中结合了用于批处理编程,实时数据处理功能,类似SQL的结构化数据处理,图形算法和机器学习的MapReduce类功能。这使它成为一个一站式的大部分大数据的需求。所以说,难怪Spark 是当今最繁忙,发展最快的Apache软件基金会项目之一。 但有些应用程序不适合Spark。由于其分布式架构,Spark 必然会给处理时间带来一些开销。这种开销在处理大量数据时可以忽略不计,但是如果你有一个数据集可以由单个机器(最近这变得越来越可能)处理,使用一些其他框架为这种计算优化可能会更有效。此外,Spark不是考虑到在线事务处理(OLTP)应用程序(快速,众多,原子事务)。它更适合在线分析处理(OLAP):批处理作业和数据挖掘。

[翻译][Spark In Action][Spark 实战 ]1.1.1 Spark 发展史

$
0
0
1.1.1 Spark 发展史 虽然过去十年看到Hadoop的广泛采用,Hadoop不是没有它的缺点。 它是强大的,但它处理速度很慢。 这为新技术(如Spark)开辟了道路,以解决Hadoop面临的相同问题,但Spark 更高效。 在接下来的几页中,我们将讨论Hadoop的缺点,以及Spark如何解决这些问题。 Hadoop框架及其HDFS和MapReduce数据处理引擎, 是第一个将分布式计算带给大众的。 Hadoop解决了 任何分布式数据处理工作面临的三个主要问题:
本文http://www.paymoon.com:8001/index.php/2016/12/27/the-spark-revolution/ 如果转载请联系 龙遥Yol  i@paymoon.com
1、并行化 - 如何同时执行计算的子集 2、分发 - 如何分发数据 3、容错 - 如何处理组件故障 注意附录A更详细地描述了MapReduce。 此外,Hadoop集群通常由商品硬件组成,这使Hadoop易于设置。 这就是为什么过去十年被广泛采用。

[翻译][Spark In Action][Spark 实战 ]1.1.2 MapReduce 缺点

$
0
0

1.1.2 MapReduce 缺点

虽然Hadoop是当今大数据革命的基础,并且被积极使用和维护,但它仍然有它的缺点,他们主要关于它的Map-Reduce组件。 MapReduce作业结果需要存储在HDFS中,才能被其他作业使用。 由于这个原因,MapReduce本身就不适合迭代算法。

此外,许多种类的问题不容易适合MapReduce的两步模式,并将每个问题分解为一系列这两个操作可能很困难。 有时,API可能很麻烦。


本文http://www.paymoon.com:8001/index.php/2016/12/27/mapreduces-shortcomings/ 如果转载请联系 龙遥Yol  i@paymoon.com

Hadoop是一个相当低级的框架,所以无数的工具已经出现了:用于导入和导出数据的工具,用于操作数据的高级语言和框架,用于实时处理的工具等。 它们都带来额外的复杂性和要求,这使任何环境复杂化。 Spark解决了许多这些问题。

[翻译][Spark In Action][Spark 实战 ]1.1.3 Spark 带来了什么

$
0
0
1.1.3 Spark 带来了什么
Spark的核心概念是一个内存中执行模型,它能够在内存中缓存作业数据,而不是像MapReduce一样每次从磁盘读取数据。这可以将作业的执行速度提高到100倍,与Map-Reduce中的相同作业相比,它对迭代算法(如机器学习,图形算法和需要重新使用数据的其他类型的工作负载)有最大的影响。 假设您有城市地图数据存储为图形。该图的顶点表示地图上的感兴趣点,并且边缘表示它们之间的可能路线,以及相关联的距离。现在假设你需要找到一个新的救护车站的位置,它将尽可能靠近地图上的所有点。该点将是图形的中心。可以通过首先计算所有顶点之间的最短路径,然后找到每个顶点的最远点距离(到任何其他顶点的最大距离),并且最终找到具有最小最远点距离的顶点来找到。完成算法的第一阶段,找到所有顶点之间的最短路径,以并行方式是最具挑战性(和复杂)的部分,但它不是不可能的。 在MapReduce的情况下,您需要将这三个阶段的每个阶段的结果存储在磁盘(HDFS)上。每个后续阶段将从磁盘读取前一个结果。但是使用Spark,你可以找到所有顶点之间的最短路径,并缓存内存中的数据。下一个阶段可以使用内存中的数据,为每个顶点找到最远点距离,并缓存其结果。最后一个阶段可以通过这个最终的缓存数据,找到具有最小点距离的顶点。您可以想象每次读取和写入磁盘时的性能提升。 火花性能是如此的好,在2014年10月,它赢得了Daytona灰色排序 竞争和设定一个世界纪录(与TritonSort,公平)通过分类100 TB 在1,406秒(见http://sortbenchmark.org)。

Spark 的易用

Spark API比传统的MapReduce API更容易使用。 要将附录A中的经典字数示例实现为MapReduce作业,您需要三个类:设置作业的主类,一个Mapper和一个Reducer,每个10行长,给出或取几个。

相比之下,以下是对Scala编写的同一个Spark程序所需要的:

[crayon-5863703d89df6602678501/] 如图1.1,显示此图形。 Spark支持Scala,Java,Python和R编程语言,因此可供更广泛的受众访问。 尽管支持Java,Spark可以利用Scala的多功能性,灵活性和函数式编程概念,这些概念更适合于数据分析。 Python和R在数据科学家和科学界中广泛传播,这使得那些用户与Java和Scala开发人员相提并论。 此外,Spark shell(read-eval-print loop [REPL])提供了一个交互式控制台,可用于实验和想法测试。 没有必要编译和部署只是为了发现一些东西不工作(再次)。 REPL甚至可用于在完整的数据集上启动作业。 [caption id="attachment_1158" align="alignnone" width="1642"]字数计数程序(word-count)演示了Spark的简洁性和简单性。 该程序显示在左侧的Hadoop的MapReduce框架中,右侧是一个Spark Scala程序。 图1.1 字数计数程序(word-count)演示了Spark的简洁性和简单性。 该程序显示在左侧的Hadoop的MapReduce框架中,右侧是一个Spark Scala程序。[/caption]
本文http://www.paymoon.com:8001/index.php/2016/12/27/what-spark-brings-to-the-table/ 如果转载请联系 龙遥Yol  i@paymoon.com
最后,Spark可以在几种类型的集群上运行:Spark独立集群,Hadoop的YARN(另一个资源协商者)和Mesos。 这给予它额外的灵活性,并使其可供更大的用户群体访问。
Spark是一个统一的平台 Spark的一个重要方面是将Hadoop生态系统中许多工具的功能组合成一个统一的平台。 执行模型是足够通用的,单个框架可以用于流数据处理,机器学习,类SQL操作,图形和批处理。 许多角色可以在同一平台上协同工作,这有助于弥合程序员,数据工程师和数据科学家之间的差距。 Spark提供的函数列表继续增长。
Spark的反模式化 Spark不适合用于异步更新共享数据(例如在线事务处理),因为它已经考虑批处理分析。 (Spark流只是在时间窗口中对数据应用批处理分析。)仍然需要专门为这些用例使用的工具。 此外,如果您没有大量数据,则可能不需要Spark,因为它需要花一些时间设置作业,任务等。 有时,一个简单的关系数据库或一个聪明的脚本可以用来比分布式系统(如Spark)更快地处理数据。 但是数据有增长的趋势,它可能会相当快地超过关系数据库管理系统(RDBMS)或您的聪明脚本。

Java操作Redis 缓存公共类 RedisUtil 和 RedisUtilSimple

$
0
0
写了一个Redis的公共类,包含两个,一个是Redis 申请和关闭的工具,一个是存取的工具。当然写一个也可以,分开了而已。 [crayon-5863703d89926543992597/] main方法里面有简单使用,直接获取和使用完关闭即可。注意关闭的时候,可以多次close, [crayon-5863703d89930132748486/] 相关的配置文件,配置一下就可以了,配置方法网上都有,这里就不再说了。
本文http://www.paymoon.com:8001/index.php/2016/12/27/redis-common-util-and-redisutil-simple 如果转载请联系 龙遥Yol  i@paymoon.com
但是这样使用方法比较麻烦,需要自己申请,自己关,比较麻烦,我只关心存取,能不能只提供这两个方法呢。于是有了下面的 [crayon-5863703d89936626165282/] 还提供了del,get的话,没有值返回的是null, del 和set都会返回之前存的值。 一般使用RedisUtilsimple就满足了缓存存取的方法。
本文http://www.paymoon.com:8001/index.php/2016/12/27/redis-common-util-and-redisutil-simple 如果转载请联系 龙遥Yol  i@paymoon.com

Java通过Jackson操作json的通用类JsonUtil

$
0
0
Jackson操作Json是公认性能最好的,于是手写了操作Json的公共类,使用jackson 2.0以上版本 最主要的用法是把任何对象转化为String的方法 [crayon-5863703d893f7828450918/] 然后是再反序列化的方法 [crayon-5863703d89401151161771/] 这个方法有重构,一个参数是返回Map,两个参数是返回的List,注意泛型是可以传参数 详细代码如下 [crayon-5863703d89406509765314/]
本文http://www.paymoon.com:8001/index.php/2016/12/27/operate-json-by-jackson-on-java/ 如果转载请联系 龙遥Yol  i@paymoon.com
这个类可以结合RedisUtilSimple做缓存的操作,会使序列化和缓存非常方便。 Redis 缓存公共类 RedisUtil 和 RedisUtilSimple

[翻译][Spark In Action 中文版][Spark 实战 ]1.2 Spark 组件

$
0
0

1.2 Spark 组件


Spark由多个专用组件组成。 这些是Spark Core,Spark SQL,Spark Streaming,Spark GraphX和Spark MLlib,如图1.2所示。 这些组件使Spark成为一个功能齐全的统一平台:它可以用于以前必须使用几个不同框架完成的许多任务。 以下是每个Spark组件的简要说明。

1.2.1 Spark 核心


Spark Core包含运行作业所需的其他组件所需的基本Spark功能。 其中最重要的是弹性分布式数据集(RDD),这是Spark API的主要元素。 它是具有适用于数据集的操作和转换的项目的分布式集合的抽象。 它具有弹性,因为它能够在节点故障的情况下重建数据集。

spark-components-paymoon-com

图1.2 主要Spark组件和各种运行时交互和存储选项

Spark Core包含用于访问各种文件系统的逻辑,例如HDFS,GlusterFS,Amazon S3等。 它还提供了具有广播变量和累加器的计算节点之间的信息共享的手段。 其他基本功能,如网络,安全,调度和数据混排,也是Spark Core的一部分。


本文http://www.paymoon.com:8001/index.php/2016/12/27/spark-components/ 如果转载请联系 龙遥Yol  i@paymoon.com

1.2.2 Spark SQL


Spark SQL提供了使用Spark和Hive SQL(HiveQL)支持的SQL子集操作大型分布式结构化数据集的功能。 通过在Spark 1.3中引入数据框架,并在Spark 1.6中引入了DataSets,简化了结构化数据的处理并实现了激进的性能优化,Spark SQL成为了最重要的Spark组件之一。 Spark SQL还可以用于从各种结构化格式和数据源读取和写入数据,例如JavaScript对象符号(JSON)文件,Parquet文件(允许与数据一起存储模式的越来越流行的文件格式) ,关系数据库,Hive等。

DataFrames和DataSet在某些时候的操作转换为对RDDs的操作,并作为普通Spark作业执行。 Spark SQL提供了一个称为Catalyst的查询优化框架,可以通过自定义优化规则进行扩展。 Spark SQL还包括Thrift服务器,外部系统(如商业智能工具)可以使用Thrift服务器通过Spark SQL使用传统的JDBC和ODBC协议查询数据。

1.2.3 Spark 流


Spark Streaming是一个从各种来源获取实时流数据的框架。 支持的流媒体源包括HDFS,Kafka,Flume,Twitter,ZeroMQ和自定义。 Spark Streaming操作从故障自动恢复,这对于在线数据处理很重要。 Spark Streaming表示使用离散流(DStreams)的流数据,它周期性地创建包含在上一个时间窗口期间进入的数据的RDD。 Spark Streaming可以与单个程序中的其他Spark组件组合,通过机器学习,SQL和图形操作实现统一的实时处理。 这在Hadoop生态系统中是独一无二的。 从Spark 2.0开始,新的结构化流API使Spark流程序更类似于Spark批处理程序。

1.2.4 Spark MLlib


Spark MLlib是从加州大学伯克利分校的MLbase项目开发的机器学习算法库。 支持的算法包括逻辑回归,朴素贝叶斯分类,支持向量机(SVM),决策树,随机森林,线性回归和k均值聚类。 Apache Mahout是一个现有的开源项目,提供在Hadoop上运行的分布式机器学习算法的实现。 虽然Apache Mahout更成熟,但Spark MLlib和Mahout都包含一组类似的机器学习算法。 但是Mahout从MapReduce迁移到Spark,他们必须在未来合并。 Spark MLlib处理用于转换数据集的机器学习模型,表示为RDD或DataFrames。

1.2.5 Spark GraphX


图形是包括顶点和连接它们的边的数据结构。 GraphX提供了用于构建图形的功能,表示为图形RDD:EdgeRDD和VertexRDD。 GraphX包含最重要的图论理论的实现,例如页面排名,连接组件,最短路径,SVD ++等。 它还提供了Pregel消息传递API,用于由Apache Giraph实现的大规模图处理的相同API,这是一个具有图算法实现和运行在Hadoop上的项目。


Spark 实战更多文章:[翻译]Spark In Action – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/27/spark-in-action-foreword/

[翻译][Spark In Action 中文版][Spark 实战 ]1.3 Spark 程序流

$
0
0
1.3 Spark 程序流
让我们看看一个典型的Spark程序是什么样子。 假设一个300 MB的日志文件存储在一个三节点HDFS集群中。 HDFS自动将文件拆分为128 MB部分(Hadoop术语中的块),并将每个部分放在集群的单独节点上(见图1.3)。 让我们假设Spark在YARN上运行,在同一个Hadoop集群中。 spark-program-flow-paymoon-com 图1.3 在三节点Hadoop群集中存储300 MB日志文件 Spark数据工程师的任务是分析在过去两周内发生了多少类型为Out-OfMemoryError的错误。 工程师玛丽知道日志文件包含公司应用程序服务器集群的最近两周的日志。 她坐在她的笔记本电脑上,开始工作。 她首先启动她的Spark shell并建立到Spark集群的连接。 接下来,她使用这个(Scala)行从HDFS加载日志文件(见图1.4): [crayon-5863703d88f3f861574585/] 1-4-paymoon-com 图1.4 从hdfs上加载一个txt文件 为了实现最大数据本地化,加载操作向Hadoop询问日志文件的每个块的位置,然后将所有块传送到集群节点的RAM。现在Spark具有对RAM中每个块(Spark术语中的分区)的引用。这些分区的总和是来自RDD引用的日志文件的行的分布式集合。或者,我们可以说,RDDs允许您使用分布式集合,就像使用任何本地,非分布式集合一样。你不必担心集合是分布式的,你也不必自己处理节点故障。 除了自动容错和分发之外,RDD还提供了一个精心设计的API,允许您以功能样式使用集合。您可以过滤集合;用一个函数映射它;减少到累积值;减去,相交或创建与另一个RDD的联合,等等。 玛丽现在有一个对RDD的引用,所以为了找到错误计数,她首先想删除所有没有OutOfMemoryError子字符串的行。这是过滤功能的工作,她这么调用: [crayon-5863703d88f49782689093/] 过滤集合后,它包含她需要分析的数据子集(见图1.5),Mary调用缓存,告诉Spark在内存中将RDD留在作业中。 缓存是我们之前提到的Spark的性能改进的基本组件。 缓存RDD的好处将在后面显而易见。
本文http://www.paymoon.com:8001/index.php/2016/12/27/spark-program-flow/ 如果转载请联系 龙遥Yol  i@paymoon.com
现在她只剩下那些包含错误子字符串的行。 对于这个简单的例子,我们将忽略OutOfMemoryError字符串可能出现在单个错误的多行中的可能性。 我们的数据工程师计算剩余行数,并将结果报告为最近两周内发生的内存不足错误数: [crayon-5863703d88f4f744175738/] Spark使她只用三行代码执行数据的分布式过滤和计数。 她的小程序在所有三个节点上并行执行。 如果她现在想要使用OutOfMemoryErrors进一步分析行,并且可能再次调用过去在内存中缓存的oomLines对象上的过滤器(但是使用其他条件),则Spark将不会再次从HDFS加载文件,就像通常那样。 Spark将从缓存加载它。 1-5-paymoon-com 图1.5 过滤集合以仅包含包含OutOfMemoryError字符串的行
本文http://www.paymoon.com:8001/index.php/2016/12/27/spark-program-flow/ 如果转载请联系 龙遥Yol  i@paymoon.com
Spark 实战更多文章:[翻译]Spark In Action – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/27/spark-in-action-foreword/

[翻译][Spark In Action 中文版][Spark 实战 ]1.4 Spark 生态

$
0
0
1.4 Spark 生态
我们已经提到了Hadoop生态系统,包括接口,分析,集群管理和基础设施工具。 一些最重要的如图1.6所示。 图1.6不是完整的7你可能会说我们没有添加一个工具,但是一个完整的工具列表将很难适应这一节。 但我们认为,这个列表代表了Hadoop生态系统中最突出的工具的一个很好的子集。 1-6-paymoon-com 1.6 Hadoop生态系统中的基本基础架构,接口,分析和管理工具,以及Spark整合或过时的一些功能 如果您将Spark组件的功能与Hadoop生态系统中的工具进行比较,您可以看到一些工具突然变得多余。例如,Apache Giraph可以替换为Spark GraphX,而Spark MLlib可以替代Apache Mahout。 Apache Storm的功能与Spark Streaming的功能大不相同,因此在许多情况下可以使用Spark Streaming。 不再需要Apache Pig和Apache Sqoop,因为Spark Core和Spark SQL涵盖了相同的功能。但是即使你有传统的Pig工作流,并且需要运行Pig,Spork项目也允许你运行Pig on Spark。
本文http://www.paymoon.com:8001/index.php/2016/12/27/spark-ecosystem/ 如果转载请联系 龙遥Yol  i@paymoon.com
Spark没有办法替换Hadoop生态系统工具(Oozie,HBase和ZooKeeper)的基础架构和管理。 Oozie用于调度不同类型的Hadoop作业,现在甚至有一个扩展来调度Spark作业。 HBase是一个分布式和可扩展的数据库,这是Spark不提供的东西。 ZooKeeper提供了许多分布式应用程序需要的常用功能的快速和强大的实现,例如协调,分布式同步,命名和提供组服务。它也用于许多其他分布式系统中的这些目的。 Impala和Drill可以与Spark共存,特别是Drill支持Spark作为执行引擎。但它们更像是竞争框架,主要跨越Spark Core和Spark SQL的功能,这使得Spark特性更加丰富(双关)。 我们之前说过Spark不需要使用HDFS存储。除了HDFS,Spark可以对存储在Amazon S3存储桶和纯文件中的数据进行操作。更令人兴奋的是,它也可以使用Alluxio(以前的Tachyon),这是一个以内存为中心的分布式文件系统或其他分布式文件系统,如GlusterFS。   另一个有趣的事实是,Spark不必在YARN上运行。 Apache Mesos和Spark独立集群是Spark的替代集群管理器。 Apache Mesos是一个带有分布式资源抽象的高级分布式系统内核。它可以扩展到具有完全容错的成千上万个节点(我们将在第12章中访问它)。 Spark Standalone是Spark特有的集群管理器,今天在多个站点上使用。 因此,如果我们从MapReduce切换到Spark,并摆脱YARN和所有的工具,Spark使过时,Hadoop生态系统剩下什么?换句话说:我们是否正在慢慢迈向新的大数据标准:Spark生态系统?
本文http://www.paymoon.com:8001/index.php/2016/12/27/spark-ecosystem/ 如果转载请联系 龙遥Yol  i@paymoon.com
Spark 实战更多文章:[翻译]Spark In Action – PayMoon贝明实验室 http://www.paymoon.com:8001/index.php/2016/12/27/spark-in-action-foreword/
Viewing all 130 articles
Browse latest View live