Quantcast
Channel: IT社区推荐资讯 - ITIndex.net
Viewing all 11853 articles
Browse latest View live

高性能网站架构之缓存篇—Redis集群增删节点

$
0
0

Redis集群添加节点

       首先我们要新建立一个节点,将redis01 复制一份改为redis07,然后修改端口号也改为7007 ,然后我们执行[root@localhost redis07]# ./redis-server redis.conf 启动以后,然后进行查看,发现有一个端口号为7007的redis实例已经启动了!我们怎么把这个redis 实例添加到集群中呢。

       在将7007 端口号的redis实例添加到集群之前,一定要确保这个redis实例没有存储过数据,也不能持久化的数据文件,否则在添加的时候会报错的!我们执行命令  ./redis-trib add-node127.0.0.1:7007 to cluster 127.0.0.1:7001 就可以将端口号为7007的实例添加到redis-cluster中。如下如所示。

        

       我们执行在任意一个客户端下执行 cluster nodes 命令,可以看到7007 已经作为主节点添加到我们的集群中了,但是可以看到他没有分配哈希槽,没有分配哈希槽的话表示就没有存储数据的能力,所以我们需要将其他节点上的哈希槽分配到这个节点上。

   

       下边我们看一下如何分配哈希槽。我们随便进入一个客户端,然后我们执行 ./redis-trib.rb reshard 192.168.20.140:7001, 就可以看到如下图所示提示,问我们需要移动多少个哈希槽,我们在这里移动1000个。

        

        完以后,又会问我们需要覆盖的节点id是什么,这个id就是我们新创建的节点id。然后让我们输入源节点,如果这里我们输入all的话,他会随机的从所有的节点中抽取1000个作为新节点的哈希槽。

       

        我们输入all以后,会出下下图所示东西,表示hash槽正在移动。

        

        移动完以后,我们进入客户端,执行cluster nodes 命令,查看集群节点的状态,我们会看到原来没有哈希槽的7007节点,分配到了1000个哈希槽,而且是不连续的。说明是从原来的三个节点中抽取的。

        

        这样我们一个新的节点就添加好了, 但是我们发现总共是7个节点,其中的六个互为住备,但有一个是有主,没有备,所以我们需要在为该节点添加一个备份节点。我们在创建一个实例,端口号为7008,启动以后我们只命令./redis-trib.rb add-node --slave127.0.0.1:7008  127.0.0.1:7007 ,第一个实例127.0.0.1:7008为备份节点,第二个实例127.0.0.1:7007为主节点。然后我们在执行,cluster nodes 命令,就会发现新添加的节点已经作为7007 备份节点开始工作了!

       

  

Redis 集群删除节点

        删除节点也分两种,一种是主节点,一种是从节点。在从节点中,我们没有分配哈希槽,所以删除很简单,我们直接执行./redis-trib.rb del-node 127.0.0.1:700865ee465423c925326a5137668541151b4c37d2d9 有两个参数ip:port  和节点的id。 我们就可以将从节点从集群中删除了。

        

        而在删除主节点的时候,因为在主节点中存放着数据,所以我们在删除之前,要把这些数据迁移走,并且把该节点上的哈希槽分配到其他主节点上。

       我们执行./redis-trib.rb reshard 127.0.0.1:7007,问我们有多少个哈希槽要移走,因为我们这个节点上有1000 个所以我们这里输入1000,如下如所示。

       

        这样期间会询问我们是否要从新分配,我们输入yes。然后就看到7007上的所有节点都被移动到了7001.这样我们就操作完了。然后再执行./redis-trib.rb del-node127.0.0.1:7007 61f786c40bcc170006a440abd7dc773e6dd15a19 ,就会看到7007 端口的实例也被从集群中移除了。

       

 

        我们进入客户端,看一下集群节点的情况。会看到7007 节点和7008 节点就都被我们移除集群了!   



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐




高性能网站架构之缓存篇—Redis集群搭建

$
0
0

1.  Redis Cluster的架构图。          

         (1)所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.

         (2)节点的fail是通过集群中超过半数的节点检测失效时才生效.

         (3)客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

         (4)redis-cluster把所有的物理节点映射到[0-16383]slot上(哈希槽),cluster 负责维护

Redis 集群中内置了 16384 个哈希槽,当需要在Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。

2.  redis-cluster投票:容错

          

         (1)领着投票过程是集群中所有master参与,如果半数以上master节点与其中一个master节点通信超时(cluster-node-timeout),认为当前master节点挂掉.

         (2):什么时候整个集群不可用(cluster_state:fail)?

         a:如果集群任意master挂掉,且当前master没有slave.集群进入fail状态,也可以理解成集群的slot映射[0-16383]不完成时进入fail状态. ps : redis-3.0.0.rc1加入cluster-require-full-coverage参数,默认关闭,打开集群兼容部分失败.

        b:如果集群超过半数以上master挂掉,无论是否有slave集群进入fail状态.

        ps:当集群不可用时,所有对集群的操作做都不可用,收到((error)CLUSTERDOWN The cluster is down)错误。

 

3.  安装环境

        Redis Cluster的安装需要的环境我们需要准备好,最重要的最难解决的就是ruby环境,在这里,给大家一个连接,如至直接安装ruby,安装不上的话,大家可以参考这篇文章 RubyGems镜像,淘宝的ruby镜像。他是没15分钟更新一次,所以跟国外的基本一样。

4.  集群搭建

        本次为实验教程,所以在一台虚拟机中进行搭建,跟在多台真机上搭建其实没有什么区别,只要保证网络通信ok就可以了!

        我们在几台机器上通过端口号的不同,搭建一个伪集群。在一个服务器上创建多个redis实例。端口号如下所示

主节点:127.0.0.1:7001 127.0.0.1:7002127.0.0.1:7003

从节点:127.0.0.1:7004127.0.0.1:7005127.0.0.1:7006

在/usr/local下创建redis-cluster目录,其下创建redis01、redis02。。redis06目录,如下:

        

         然后我们将redis 安装到redis01中,安装完以后我们在将Redis编译目录中的redis。Conf文件复制到redis01目录下,就会看到在redis01目录下会有如下的文件。

        

         然后我们将redis01文件夹的文件分别复制到redis02……redis06文件夹中。同时将redis源码目录src下的redis-trib.rb拷贝到redis-cluster目录下。

        修改每个文件夹下的配置文件,有三点需要修改,每个配置文件都要配置自己的端口号,不能重复。

        

        准备好以上工作以后,我们分别启动每个redis进行的实例。如果麻烦的话,可以自己写一个执行脚本。启动完毕以后我们输入命令ps ax|grep redis ,查看实例是否启动,出现如下所以图片,表示所有的实例都启动了。

       

       实例启动完以后,我们要开始创建集群,在redis-cluter文件夹下执行如下命令。

  1. ./redis-trib.rbcreate --replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004127.0.0.1:7005 127.0.0.1:7006。
  2. >>> Creating cluster
  3. Connecting to node 127.0.0.1:7001: OK
  4. Connecting to node 127.0.0.1:7002: OK
  5. Connecting to node 127.0.0.1:7003: OK
  6. Connecting to node 127.0.0.1:7004: OK
  7. Connecting to node 127.0.0.1:7005: OK
  8. Connecting to node 127.0.0.1:7006: OK
  9. >>> Performing hash slotsallocation on 6 nodes...
  10. Using 3 masters:
  11. 127.0.0.1:7001
  12. 127.0.0.1:7002
  13. 127.0.0.1:7003
  14. Adding replica 127.0.0.1:7004 to 127.0.0.1:7001
  15. Adding replica 127.0.0.1:7005 to 127.0.0.1:7002
  16. Adding replica 127.0.0.1:7006 to 127.0.0.1:7003
  17. M: 5a8523db7e12ca600dc82901ced06741b3010076127.0.0.1:7001
  18. slots:0-5460 (5461 slots) master
  19. M: bf6f0929044db485dea9b565bb51e0c917d20a53127.0.0.1:7002
  20. slots:5461-10922 (5462 slots) master
  21. M: c5e334dc4a53f655cb98fa3c3bdef8a808a693ca127.0.0.1:7003
  22. slots:10923-16383 (5461 slots) master
  23. S: 2a61b87b49e5b1c84092918fa2467dd70fec115f127.0.0.1:7004
  24. replicates 5a8523db7e12ca600dc82901ced06741b3010076
  25. S: 14848b8c813766387cfd77229bd2d1ffd6ac8d65127.0.0.1:7005
  26. replicates bf6f0929044db485dea9b565bb51e0c917d20a53
  27. S: 3192cbe437fe67bbde9062f59d5a77dabcd0d632127.0.0.1:7006
  28. replicates c5e334dc4a53f655cb98fa3c3bdef8a808a693ca
  29. Can I set the above configuration? (type'yes' to accept): yes
  30. >>> Nodes configuration updated
  31. >>> Assign a different configepoch to each node
  32. >>> Sending CLUSTER MEET messagesto join the cluster
  33. Waiting for the cluster to join.....
  34. >>> Performing Cluster Check(using node 127.0.0.1:7001)
  35. M: 5a8523db7e12ca600dc82901ced06741b3010076127.0.0.1:7001
  36. slots:0-5460 (5461 slots) master
  37. M: bf6f0929044db485dea9b565bb51e0c917d20a53127.0.0.1:7002
  38. slots:5461-10922 (5462 slots) master
  39. M: c5e334dc4a53f655cb98fa3c3bdef8a808a693ca127.0.0.1:7003
  40. slots:10923-16383 (5461 slots) master
  41. M: 2a61b87b49e5b1c84092918fa2467dd70fec115f127.0.0.1:7004
  42. slots: (0 slots) master
  43. replicates 5a8523db7e12ca600dc82901ced06741b3010076
  44. M: 14848b8c813766387cfd77229bd2d1ffd6ac8d65127.0.0.1:7005
  45. slots: (0 slots) master
  46. replicates bf6f0929044db485dea9b565bb51e0c917d20a53
  47. M: 3192cbe437fe67bbde9062f59d5a77dabcd0d632127.0.0.1:7006
  48. slots: (0 slots) master
  49. replicates c5e334dc4a53f655cb98fa3c3bdef8a808a693ca
  50. [OK] All nodes agree about slotsconfiguration.
  51. >>> Check for open slots...
  52. >>> Check slots coverage...
  53. [OK] All 16384 slots covered.
复制代码

 

这样就表示我们的集群创建成功了!

5.  集群测试

        我们输入redis01/redis-cli -h 127.0.0.1  -p 7002–c命令后,切忌要加入-c,否则我们进入的不是集群环境。进入客户端以后,我们输入set a 100 发现他会进行跳转,这就是因为他经过计算以后,要存储100的hash槽在7003 实例上。这样就表示我们的集群成功了!

        

         关闭redis集群不能直接kill掉进程,或者关机,我们要通过命令redis01/redis-cli -p 7001 shutdown进行关闭,这样在关闭之前,数据才能够进行保存。



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



从三大关键技术来看,未来的服务机器人会是什么模样?

$
0
0

从三大关键技术来看,未来的服务机器人会是什么模样?

根据 IFR 发布的 2016 年世界服务机器人统计报告,全球专业服务机器人 2015 年总销量为 4.11 万台,与 2014 年的 3.29 万台相比上升了 25%,总销售额为 46 亿美元,同比上升 14%。而在个人/家庭服务机器人领域,2015 年约售出 540 万台,同比增长 16%,销售额为 22 亿,较 2014 年增长4%。

在数据呈现之外,对于服务机器人,国家和相关团体也给予了重视。比如中国机器人产业联盟,就在不久前,其宣布将陆续发布 3 项联盟标准和 17 项机器人产业联盟标准。

从这种种迹象来看,在可预见的未来,服务机器人的前景是极其可观的。说白了,机器人就是一个各项技术的综合体,而按照大方向来分类,主要分为三部分,分别是感知、认知交互和运动控制。

感知——智能的第一步

通常来讲,机器人的感知就是借助于各种传感器来识别周边环境,相当于人的眼、耳、鼻、皮肤等:

视觉感知:即计算机视觉,类比于人类的视觉系统。用摄影头代替人眼对目标进行识别、跟踪和测量等。

当前,服务机器人的计算机视觉已经相当完善了,像人脸识别、图像识别、定位测距等等。可以说,在为人类提供服务时,“看得见东西”的机器人比“盲人”机器人有用的多。

声音感知:即语音识别,语音是人机交互最常用、最便捷的方式,由此,对于服务机器人而言,语音识别是必须具备的重要功能之一。

“服务机器人在语音识别上已经超过了人类。”此前,清华教授、中国人工智能学会理事孙富春曾这样表示。如果仅仅只是在表面上识别文字,参看科大讯飞语音识别 97% 的准确率,服务机器人确确实实已经达到了人类的需求水平。而在此后,服务机器人的目标则是进一步深入文字的背后。

其他感知:在服务机器人身上,以上两种最重要的感知已经得到了完美的体现,而在其他的方面,人们仍处在不断的探索之中。

以“皮肤感知”为例,为了让机器人在外表更接近人类,以及更多的感知,不少团队一直在努力研究一种“敏感皮肤”,力图做到柔软、敏感性强等特性。在此之上,已经有不少成果展现在了公众的面前,微风、蚊虫降落等感知已是小菜一碟。此外,还有嗅觉等等,这些都是一个服务机器人所应具备的功能。

认知交互——服务机器人价值实现的关键

不管是人类还是机器人,感知都是最基层的一部,而认知则是往上再进一步的升华。在认知的基础上,服务机器人才能理解人类的各个方面,才能与人类更自然的进行交互:

自然语言处理:前面提到,在识别语音之后,服务机器人所要做的就是深入文字的背后,这指的就是“自然语言处理”。

目前,自然语言处理这块可以说是服务机器人的一大缺陷。虽然服务机器人也可以与人类进行一些连续语音交互,但其仍不能达到令人满意的程度。或许也可以这样说,服务机器人较好的做到了自然语言处理,但在自然语言理解方面仍是一个“牙牙学语的婴孩”。

深度学习:在人类面前,机器人就是一张白纸,它们需要学习人类的各方面,像说话、做家务等等,而在这方面,深度学习算法就是一个关键。

利用深度学习算法,在加以大量数据的训练,服务机器人就可以模仿人类形成自己的一套做事方法,并在之后加以运用。以人脸识别为例,科学家们利用数据库中的人类照片对算法进行训练,让之将照片与人名相对接,在不断的纠错中提高其识别的准确率。

如果将人工智能技术的研究比作造房子的话,深度学习算法就是最底下的“地基”,承担着一项技术的所有“风险”。此外,在认知交互方面,除了语义理解和向人类学习,服务机器人还需要对“感情”进行理解,如此,它才能够真正的贴近人类,实现自己的真正价值,尤其是注重情感交流的陪护型服务机器人。

从三大关键技术来看,未来的服务机器人会是什么模样?

运动控制——足式机器人是未来趋势

在运动控制上,服务机器人主要涉及两方面,一个是定位导航,一个是平衡性。

定位导航,服务机器人需要完成定位、建图和路径规划,对此,大部分公司采取的都是 SLAM 技术。以扫地机器人为例,借助于计算机视觉和 SLAM 技术,其系统内部将进行建图和路径规划,在此之后,扫地机器人在运转过程中将不再是没头没脑的乱撞,而是能够有规划的扫地,并自行返回充电,毫不拖泥带水。

而在 平衡性上,纵观市面上的服务机器人,九成以上都是轮式或履带式,足式机器人是相当之少见。

相比如足式,轮式和履带式底盘的确具有更强的稳定性、可靠性和耐用性。从当前市场来看,这两种底盘是最适宜的选择,然而,从长远的角度来讲,足式机器人才是未来趋势。轮式和履带式底盘将服务机器人的运动范围局限在了平地和一点点坡度的地面,而在未来,服务机器人的服务范围必将扩大,行走环境也将变得多样化,比如楼梯,因而其底盘也必须得到改变。

从三大关键技术来看,未来的服务机器人会是什么模样?

未来,服务机器人的家庭普及率将逐年增长,与此同时,服务机器人的性能也会在用户的体验反馈中不断提升。

需要注意的是,以上所提技术皆为机器人本身所搭载的技术,做到了这些,服务机器人只是实现了“机器人”的价值。而在“服务”上面,服务机器人和厂商还需做其他的工作,比如接口协议的统一、机器人的通信技术等等。

【钛媒体作者:镁客网。微信公众号“镁客网”,微博@镁客网】

本文链接

探究如何给Python程序做hotfix

$
0
0

使用Python来写服务器端程序,很大的一个优势就是可以进行热更新,即在不停机的情况下,使改动后的程序生效。在开发阶段,这个功能可以大大提高开发效率(写代码–启动服务器–看效果–改代码–hotfix–看效果–提交~);而在生产环境中,可以以最小的代价(不停机)修复线上的bug。

我在项目中使用hotfix功能很长世间了,大概了解它是利用了Python的import/reload功能,但是并没有去自己研究过。最近看了云风大大写的一篇文章: 如何让 lua 做尽量正确的热更新,收获很多。也觉得应该研究一下Python的hotfix机制,毕竟是跟了自己这么久的小伙伴嘛。

import

说到hotfix就要从import语句说起。

首先建立这样一个简单的文件用作测试。

test_refresh.py
from __future__ import print_function

class RefreshClass(object):
    def __init__(self):
        self.value = 1

    def print_info(self):
        print('RefreshClass value: {} ver1.0'.format(self.value))

version = 1.0
  
print(version)

下面启动一个python解释器。

>>> import test_refresh as tr
1.0>>> import test_refresh as tr>>>> # edit  version=2.0>>> import test_refresh as tr>>> tr.version
1.0

重新import一个已经import过的模块,并不会重新执行文件(第二个import之后没有输出)。后面修改源文件并重新import后,对内存中tr.version的检查也验证了这一点。

为了能够重新加载修改后的源文件,我们需要明确的告诉Python解释器这一点。在Python中,sys.modules保存了已经加载过的模块。所以

>>> del sys.modules['test_refresh']>>> import test_refresh as tr
2.0>>> tr.version
2.0

在将test_refresh从sys.modules中删除之后再进行import操作,就会重新加载源文件了。

另外,如果我们只能拿到模块的字符串名字,可以使用__import__函数。

# edit version=3.0>>> del sys.modules['test_refresh']>>> tr = __import__('test_refresh')
3.0>>> tr.version
3.0

reload

当我们面对的是一个之前已经import过的模块时,可以直接使用reload进行重新加载。

# edit version = 4.0>>> reload(tr)          
4.0<module 'test_refresh' from 'test_refresh.py'>>>> tr.version
4.0

初步尝试hotfix

知道了模块重新加载的方法后,我们在Python的交互式命令行中,尝试动态改变一个类的行为逻辑。

test_refresh.py
from __future__ import print_function

class RefreshClass(object):
    def __init__(self):
        self.value = 1

    def print_info(self):
        print('RefreshClass value: {} ver1.0'.format(self.value))

这是测试类的当前状态。

我们创建一个该类的对象,验证下它的行为。

>>> a = tr.RefreshClass()>>> a.value
1>>> a.print_info()
RefreshClass value: 1 ver1.0

符合预期。

接下来,修改类的print_info函数为ver2.0,并reload模块。

# edit print_info ver2.0>>> reload(tr)
4.0<module 'test_refresh' from 'test_refresh.py'>>>> a.value
1>>> a.print_info()
RefreshClass value: 1 ver1.0

输出并没有如预期一样输出ver2.0……

那我们重新创建一个对象试试。

>>> b = tr.RefreshClass()>>> b.value
2>>> b.print_info()
RefreshClass value: 2 ver2.0

新对象b的行为是符合重新加载后的逻辑的。这说明,reload确实更新了RefreshClass类的行为,但是对于已经实例化的RefreshClass类的对象,却没有进行更新。对象a中的行为还是指向了旧的RefreshClass类。

在Python中,一切皆是对象。不仅实例a是对象,a的类RefreshClass也是对象。

这时,要修改a的行为,就需要用到a的__class__属性,来强制使a的类行为指向重新加载后的RefreshClass对象。

>>> a.__class__ = tr.RefreshClass>>> a.value
1>>> a.print_info()
RefreshClass value: 1 ver2.0

由于value是绑定在实例a上的,所以它的值并不会随RefreshClass的改变而改变。这也符合hotfix的预期逻辑:更新内存中实例的行为逻辑,但是不更新它们的数据。

接下来,我们还可以通过print_info函数的im func属性,验证在更改了\_class__属性后,函数确实更新成了新版本。

# edit print_info ver3.0>>> reload(tr)
4.0<module 'test_refresh' from 'test_refresh.py'>>>> a.print_info.im_func<function print_info at 0x7f50beeb2c08>>>> c = tr.RefreshClass()>>> c.print_info()
RefreshClass value: 3 ver3.0>>> c.print_info.im_func<function print_info at 0x7f50beeb2cf8>>>> a.__class__ = tr.RefreshClass>>> a.print_info.im_func<function print_info at 0x7f50beeb2cf8>>>> a.print_info()
RefreshClass value: 1 ver3.0

触发hotfix

上面的操作都是在Python的交互式解释器中运行的。下面我们将尝试使一个运行中的Python程序进行热更新。

这里遇到一个问题:作为Python程序入口的那个文件,不是以module的形式存在的,因此不能用上面的方式进行hotfix。所以我们需要保持入口文件的尽量简洁,而将绝大多数的逻辑功能交给其他的模块执行。

要触发一个正在运行中的Python程序进行热更新,我们需要有一种方式和Python程序通信。直接使用OS的标识文件是一个简单易行的方法。

test_refresh.py
from __future__ import print_function

import os
import time
import refresh_class


rc = refresh_class.RefreshClass()
while True:
    if os.path.exists('refresh.signal'):
        reload(refresh_class)
        rc.__class__ = refresh_class.RefreshClass
    time.sleep(5)
    rc.print_info()
refresh_class.py
class RefreshClass(object):
    def __init__(self):
        self.value = 1

    def print_info(self):
        print('RefreshClass value: {} ver1.0'.format(self.value))

每次我们修改完refresh_class.py文件,就创建一个refresh.signal文件。当refresh执行完毕,删除此文件即可。

这种做法一般来讲,会导致多次重新加载(因为一般不能及时的删除refresh.signal文件)。

所以,我们考虑使用Linux下的信号量,来同Python程序通信。

test_refresh.py
from __future__ import print_function

import time
import signal

import refresh_class

rc = refresh_class.RefreshClass()


def handl_refresh(signum, frame):
    reload(refresh_class)
    rc.__class__ = refresh_class.RefreshClass


signal.signal(signal.SIGUSR1, handl_refresh)
while True:
    time.sleep(5)
    rc.print_info()

我们在Python中注册了信号量SIGUSR1的handler,在其中热更新RefreshClass。

那么只需在另一个terminal中,输入:

kill -SIGUSR1 pid

即可向pid进程发送信号量SIGUSR1。

当然,还有其他方法可以触发hotfix,比如使用PIPE,或者直接开一个socket监听,自己设计消息格式来触发hotfix。

总结

以上进行Python热更新的方式,原理简单明了,就是利用了Python提供的import/reload机制。但是这种方式,需要去替换每一个类的实例的__class__成员。这就往往需要在某处保存目前内存中存在的所有对象(或者能够索引到所有活动对象的根对象),并且在类的设计上,需要所有类的基类提供一个通用的refresh方法,在其中进行__class__的替换工作。对于复杂的类组合方式,这种方法比较容易在热更新的时候漏掉某些实例。

其实还有一种途径可以代替__class__的替换工作。我们知道,如果不替换__class__的话,即使我们重新加载进来了新的module,但是所有的__class__还将指向旧的module的class。那么,我们不妨将新的module的内容插入到旧的module中。这样我们就可以不用费劲去更新每一个__class__了。一般的,我们会利用import hook(sys.meta_path,详见 PEP302)来实现这个替换。当然,这种方法的实现细节较多(因为module中可能存在module,class,function等互相嵌套的情况),不过只要实现完整后,就是一劳永逸的事情了。

相关代码可以在GitHub上找到 py-refresh

转载请注明出处: http://blog.guoyb.com/2016/12/13/py-hotfix/

欢迎使用微信扫描下方二维码,关注我的微信公众号TechTalking,技术·生活·思考:

不可错过的Node流行框架介绍

$
0
0

前言

Node.js是由Ryan Dahl于2009年创建的。它是一个开源的跨平台运行时环境,用于开发服务器端和网络应用程序,它是基于Google Chrome V8 JavaScript引擎构建的。Node.js使用事件驱动,非阻塞I/O模型而得以轻量和高效,非常适合在分布式设备上运行数据密集型的实时应用。你可以通过在Node.js中运行JavaScript,使用Ruby或者PHP语言做想做的任何事情。
由于其具有可以方便地搭建响应速度快、易于扩展的网络应用等特性,Node.js受到了Netflix,Groupon,PayPal,LinkedIn,Uber,eBay等公司的信任,这进一步促进了Node.js的发展。
也因为它响应快,易于扩展等特点,也是实战开发的首选。开发人员之所以喜欢Node.js,是因为其将脚本语言(JavaScript)的易用性和有着各种框架可供选择的Unix网络编程的强大功能相结合了。

Node特点

1、快速:V8 Google Engine授权Node.js提供一个快速发布周期。这使得网络连接,文件系统和数据库的读取和写入超级快。
2、实时性:websocket协议的强大功能允许客户端和服务器之间轻松快速通信。它是即时的,是实时应用程序的理想选择,如聊天或游戏这类应用。
3、灵活:开发人员可以为客户端,服务器端,后端和前端应用程序使用相同的语言(可以同时执行),它提供端到端的解决方案。
4、跨平台支持:Node.js可以在任何操作系统上虚拟运行。这意味着Node.js可移植,所以,应用程序能够支持广泛的用户受众。
5、单线程:Node.js在不新增额外线程的情况下,依然可以对任务进行并行处理——Node.js是单线程的。它通过事件轮询(event loop)来实现并行操作,对此,我们应该要充分利用这一点——尽可能的避免阻塞操作,取而代之,多使用非阻塞操作。
6、事件循环:Node.js使用事件循环来代替可伸缩性,而不是进程或线程。服务器在回调定义结束时自动进入事件循环。
7、社区:Node.js背后有一个强大的,多样化的,活跃的和快速扩张的社区支持。开发人员使用Github共享成果,提出功能请求、上传包或进行错误修复。

流行的开源Node.js框架

针对现在开源比较流行的几大框架做一个简单的介绍,并不深究。

Actionhero

这是一个用于Node.js的快速,轻量级和多重传输的API服务器,非常适合用于创建一个易于使用的工具包来制作可重用和可扩展的API。
可以提供给http sockets,tcp sockets和web sockets。actionHero.js提供创建易用的,可重用可伸缩的API工具包。客户端连接到actionHero.js服务器就可以使用APIs,使用静态内容和相互沟通。
actionHero.js服务器可以处理请求和任务(延迟action 比如:send e-mail或者是后台任务)。
Github stars:1,499
Github contributors: 67

Loopback

这是一个由IBM创建的高度可扩展的API框架,允许使用非常少的编码创建动态的端到端REST API。它通过为开发人员提供一个简单的API工具来补充Express框架。
Loopback API可以连接设备,并与Android,iOS和AngularJS SDK集成以创建客户端应用程序。对于应用程序的图形版本,Loopback使用StrongLoop Arc。
Github stars: 7,817
Github contributors: 80

Restify

这是一个为REST API而创建的轻量级框架,它是一个通过API提供数据的服务器端框架。Restify重点关注调试和分析,以优化服务器。
Github stars: 5,966
Github contributors: 142

Socket.io

该框架的目的是支持实时web应用(例如文档协作和数据交换)。Socket.io允许Web客户端和服务器之间的事件驱动通信。socket.io是一个跨平台,多种连接方式自动切换,做即时通讯方面的开发很方便,而且能和expressjs提供的传统请求方式很好的结合,即可以在同一个域名,同一个端口提供两种连接方式:request/response, websocket(flashsocket,ajax…).
Github stars: 28,887
Github contributors: 123
Full Stack
以下框架专注于全栈支持,它们涵盖了应用程序开发的每一步,从中间件和UI到API和数据库集成。

Meteor

Meteor是用于构建实时web应用程序的模型视图控制器(MVC)框架,其与服务器不断同步。它是内置的一套预编写自包含模块,支持应用程序代码编写。
使用Meteor构建的应用程序可以在OS X,Windows和Linux操作系统上运行。
Github stars: 36,081
Github contributors: 321

Keystone

此框架是数据库驱动Web应用程序和API的理想选择,其中Express,MongoDB和Mongoose是Node堆栈的关键组件。
Github stars: 8,352
Github contributors: 181
Sinatra-Like
以下是轻量级框架,其功能类似于Sinatra。

Express

Express是基于Node.js平台快速、开放、极简的web开发框架。Express是最重要的节点框架之一,是构建Web/移动应用程序和API的理想选择。Express不是对Node.js已有的特性进行二次抽象,只是在它之上扩展了Web应用所需的基本功能。
Github stars: 28,683
Github contributors: 192

Koa

这是一个无回调的轻量级中间件框架,允许编写Web应用程序和REST API,还可以添加新功能并自定义路径中的内容,它支持ES6和最新的JavaScript版本。
对于Node.js的初级者来说,这不是理想的第一选择。
Github stars: 12,779
Github contributors: 91

Hapi

Hapi框架是快速构建和API测试的理想选择,也可以使用Hapi构建完整的网站。它有一个十分不错的插件集合,使其能够在不破坏其余代码库的情况下,只在局部进行工作,对于团队项目而言十分受用。
由于Hapi是由Walmart开发人员创建的,因此它提供了企业级功能。
Github stars: 7,015
Github contributors: 151

在几年的时间里,由于Node.js诸多的有点,收到企业和开发者的欢迎,逐渐发展成了一个成熟的开发平台,吸引了许多开发者,并进一步促进大前端的发展和快速移动框架的发展。

专访 GrowingIO 创始人张溪梦,数据分析可以发现哪些“惊天秘密”

$
0
0

张溪梦,GrowingIO 创始人兼 CEO,曾是一位脑肿瘤外科医生,随后“弃医从文”,选择投身互联网大潮。在美国,他曾担任 LinkedIn(领英)美国商业分析部高级总监,曾被评为“世界前十位前沿数据科学家”。

2015年,他回国创业,建立 GrowingIO。

作为“增长黑客”理论在中国的实践者,他试图通过对用户行为的精细分析,对互联网产品进行针对性的快速迭代,从而使客户出现指数型的增长。

【GrowingIO 创始人&CEO 张溪梦】

作为雷锋网的专栏作者,他曾经发表过很多数据分析方面的干货文章。在最近举办的 GrowingIO 数据增长大会上,雷锋网对张溪梦进行了专访。

以下是访谈内容。

雷锋网:GrowingIO 一直在强调“无埋点”的技术,也就是不用在程序代码中预埋采集数据信息的SDK,而是通过收集用户的点击、操作行为来取得“行为数据”。有人认为这种数据并不准确,存在弊端,你怎么看?

张溪梦:

数据分成几个类别。

第一阶段,就是最基础的就是交易类型的数据,这些数据非常小,是以 M 计算的。


第二阶段,就是 CRM(客户管理系统)中的用户数据。


第三阶段,就是用户行为。你看了什么东西,买了什么东西,浏览了什么商品,是否加入了购物车,是否增加了社交关系。它的数据量应该是前两类的一千到两万倍。

用户数据在今天已经被很好地搜集了,而对行为数据的搜集是缺失的。我们的技术主要用来收集的正是行为数据。根据过去十年数据分析的经验,我觉得数据本身只要反应出趋势就足够了。

利用这种技术对于用户行为的收集,很多确实并不是百分百反应了用户在网站上真正的行为,有或多或少的缺失。我觉得 数据缺失是很正常的,但是数据必须要稳定。如果这次收集到 95% 的用户行为,就要保证能够持续地收集到95%,不是说今天 95% 明天 20% 了。

所以数据的稳定性要重于每个细节的正确性。当然,在交易型的数据里我们要求百分之百的准确。而很多行为数据用于预测,预测本身就是一个不是特别准的事情,所以效果如何还是得看最后的用法。

雷锋网:对于很多用户来说,他的核心业务数据分析可能是用埋点做的。如果用户希望埋点和无埋点的方式结合,是否存在困难?

张溪梦:

这就是我们 GrowingIO 建立的核心原因,我们从来没想过把数据用户的“仓库”和内部的 BI 系统完全打破了搬到云上去,这不是我们建造 GrowingIO 的初衷。以前我在领英的时候,核心的交易数据还是在传统的 ERP 系统里。电子商务公司他们有一个电子数据库,我们再把它复制一遍是浪费大家时间。

但是用户行为数据这是很多公司都很头疼的。只有大型的互联网公司,像领英、像京东,拥有几千人的团队才可能有人做这件事。我们可以把数据回传给用户,让他们内部进一步做数据的中心化。例如点融网,他们用了 GrowingIO 的数据做反欺诈的实时风控,以前需要几个工程师收集这些东西,现在是加一行代码自动就产生了。

用户行为数据,包括很多层面,例如用户倾向,就是这个用户想干什么,他是体育的粉丝,篮球粉丝?他有什么需求?

这些数据都需要最后交给我们服务的客户的,我们不想拥有这些数据,因为我们不做数据业务。我们是帮助客户做精细化运营,所以原始的数据我们并不会攥在手里,而是给到用户。 用户可以用这些数据做进一步的个性化利用。

【用户的行为数据,可以做精细化的分类采集】

雷锋网:GrowingIO 所有的分析都建立在云端,有没有客户担心数据外泄?有没有可能建立私有的数据分析中心?

张溪梦:

我们的客户大部分人都对数据的保密性、安全性有顾虑,特别是早期去年2015年的时候。现在所有的上云的客户都有这个顾虑。

但是我觉得从本质来说,我们希望能够在一秒钟内把数据处理完交给客户,具体这个数据在哪个云里哪个系统里不重要。只不过我们今天采用的方案有一个巨大的好处:

我们今天处理的数据量是领英的5倍到10倍,整套框架大概有一千亿用户,但我们的投入的成本可能是领英的百分之一。如果用户建造私有的分析系统,成本可能是使用云的一百倍。

比如说我想吃日本料理,我没有必要盖一个日本的厨房请一个厨师。

我们想把用户分析成品化,这样可以降低成本。它能把节省的工程师资源用在开发核心产品和功能上面,这是我们放在云端核心的原因。

我们至今都没有做内部的版本。因为内部的版本涉及到服务集群,还需要内部有运维的团队,还要有分析师。未来信息产生的速度非常非常快,这种就要求产品迭代非常快,如果我们(在内部系统)安装完了软件之后,有可能迭代都会产生问题。

所以云端的方式,在长远上讲,无论在性价比、性能、最终的管理上还是 IO 上都是最好的。对于有顾虑的厂商我们也做了一些工作,例如对数据进行加密,去掉敏感信息,用户可以自己配置不采集他认为敏感的信息。

雷锋网:GrowingIO 系统需要很大比重的分析师人工服务辅助吗?

张溪梦:

任何企业服务的公司,都一定是产品和人的相对结合的过程。

可能产品在发展的初期,人的成分会更多一些,现在真正服务客户企业的,很多都是我们的分析师给他们输入。不是说我们的产品不能做东西,而是他们(客户)自己缺乏分析的思路、经验和框架。

未来我们想做的产品,是把分析师的思路相对统一地做到产品里去,用产品的人就自然而然具备了这种思路。就不用分析师教给他:你先观测、找原因、分析道理,核心的造成衰减和增长的原因,怎么样改变和执行。

这套模型应该变成自动的,但是自动化的过程,是人和机器学习的过程。比如说:

一个产品现在不是百分之百自动满足客户的需求,但是有人教客户;

之前是人在收集客户反馈,以后产品就会慢慢收集人的行为。

我们的产品就变得越来越智能,人的成分就越来越低。其实不是想替换人类,是因为好的分析师、增长黑客太稀缺了,只能用产品弥补人员的缺失。

雷锋网:未来数据分析服务会是怎样的形态?

张溪梦:

以后产品是这样的形态,用户只需要告诉我们他关注什么,比如说关注我的注册。他选择这个结果以后,产品应该自动帮他分析出来有关“注册”哪里有问题,例如是针对人群的问题还是产品设计的问题。

如果是产品功能的问题,你需要如何改进;

如果好似投放给了错误的人群,应该如何更换渠道。

我们希望未来 第一步是做到能够判断用户需要解决什么问题,然后由我们的产品告诉他。要做到这样,早期应该只针对特定的几个行业,这几个行业如果做的好的话,这种模型可以复制到其他行业。

雷锋网:数据分析、增长黑客在未来应该会有很大的市场,你是否担心大公司砸重金进入这个市场呢?

张溪梦:

我从来没有担心过,好多人问我你担心IBM进来吗,我完全不担心。因为我们做的东西根本没有在这个世界上出现过,他只能砸钱。但是几十万亿资本砸进来,做出来是什么东西呢?

一个产品本身是有性格的,是有人的本性,有 DNA 的,而 DNA 是无法复制的。数据分析的关键在于分析,是非常个人化的。换句话说,我们要做的产品是要反映我们这些人的灵魂的。而你很难复制一个人的灵魂。

巨头砸钱,说明市场需要教育。这个过程中参与的人越多越好。

BAT 他们都有很强的分析能力,我觉得大部分厂商也愿意开放这些能力。但对数据本身的理解,每个人都有自己的版本,这种世界观会反应在产品以后的形态里,会非常不一样,各有特点。

问:GrowingIO 有一个重要的功能“热力图”,可以科普一下其中的原理吗?

张溪梦:

热力图分为三种层次:

第一种是非常粗糙的,是收集人眼看被吸引到屏幕的哪个位置。但人被吸引注意力取决于三个东西:大小、形状、颜色。所以会有多种因素引导视觉。这是神经学的科技分析,我们今天做的不是这块。


第二种是记录用户在屏幕上像素点的点击。比如说一个屏幕的分辨率是 800×600,包含48000个像素点。热力图会记录用户在哪里点击。


第三种热力图同样是记录点击,但是点击的数据不是跟着屏幕,是是跟着内容走的。例如一条新闻,它会记录用户在长长的新闻中,在各个具体位置的点击行为。    

我们做的是第三种。用户点击操作的界面,热力图的核心在内容上。这样的话我们能帮用户不单分析界面,同时还分析内容。之前我们发布的产品是针对PC端的网站,这次我们发布了移动端的产品。可以记录用户在手机上点击的“热力图”。

雷锋网:增长黑客的成功案例是 Uber、亚马逊。但是 Uber 在中国败给了滴滴,亚马逊在中国败给了淘宝京东,问题出在哪里?

张溪梦:

第一,之所以今天Facebook、亚马逊等公司变得非常知名,是因为他们公司在早期、中期持续地在做这件事。

他们持续增长的原因有三个:

一是有商业模式,


二是运营非常系统化,


另外就是“增长黑客”体系的帮助。

中国的很多企业以前并没有关注增长体系,这种情况下还能打赢,我觉得有以下的原因:

首先,是中国用户基础大,什么 App 一做就有几百万用户上来,因为中国有十几亿人。这个情况在美国2000年的时候有可能,现在想做到这样的已经很难了,所以他们需要做“Growth Hack”。


其次,中国资本红利在衰退,大家更理性了,没有人盲目投资。不盲目投资的情况下我们就更需要关注效率。这就是为什么很多大型企业在迅速地吸纳“增长黑客”这套方法论的知识和建团队的原因。

“增长黑客”的核心理念是:你要把以前的市场营销预算变成工程和产品的预算。

以前市场营销有很多预算,但这些预算都被无效地花出去了。如果把这些预算拿出来很少一部分变成工程师和产品经理的预算,效果可能大不一样。中国以后也会把烧钱、烧流量、大投放的方法慢慢转化成非常聪明的用工程产品的内升的自然生长的方法来解决问题。亚马逊这样公司的运营效力不能说到极致了,但是接近极致了。

雷锋网:是否可以举一个例子,曾经“烧钱”的客户怎样通过“增长黑客”提升用户数量?

张溪梦:

有一位互联网金融的客户,他们的获客成本成本在过去两年半里,增加了几百倍。

使用这种方法,他们找到了很多核心原因。

第一,在中国有一个有趣的现象是 “薅羊毛”。很多人简单做一些注册动作,就把利润拿走,并不会成为客户来购买他们的理财产品。


第二, 他们发现 不同获客渠道之间的差异竟然是巨大的。有些渠道的效力非常低,但他们在分析数据之前根本不知道。


第三,他们解决了时间问题。以前做一个活动,需要等两三个星期才能知道效果。现在基本 当天或者隔天就可以知道结果。

这是他原话是:如果两年前他使用 GrowingIO 的话,今天的互联网金融格局应该是不一样的。

很多用户需要的不止是一个数据,他需要一下子就能看到其中的问题,然后赶快修改。对于创业企业,资本投放都是次要的,关键的是时间。因为一个创业公司真正想生存下去,取决于单位时间内你能跑多快跑多远。不可以一个星期一个星期地浪费。

【访问用户实时走势/图片由 GrowingIO 提供】

雷锋网:“增长黑客”技术未来会有怎样的趋势?

张溪梦:

美国的那套增长系统,比我阐述的复杂一百倍。我认为它在理念上没必要再进化了,关键是怎么落地。怎么样把运营的小环都闭合了。像一个小齿轮就是增长的一个小环节,当很多种齿轮在一起就组成了一个引擎,这个引擎连接的是产品研发、市场营销、工程实现、销售、客户服务和客户支持、风控各个部门,还有财务。这套体系是下面几年里中国的公司需要去批判接纳的,就是一定要适合中国企业形式和发展的速度。它是科学化管理体系,只要有了正确的方法、正确的人和正确的流程,不断地践行就一定能看到效果。

国内三大红利结束以后,各个企业应该做“增长黑客”这件事,这是专业化的表现。

增长黑客之父 Sean Ellis :如何复制“爆炸性增长” | 演讲全文&专访

$
0
0

12月17日 Growing Io 数据驱动增长大会邀请到了硅谷大咖,“增长黑客理论”(Growth Hacking)之父 Sean Ellis 来到了现场。

Sean Ellis 在2010年提出增长黑客理论,核心理论就是通过对用户行为数据的精细挖掘,有针对性地对产品进行快速迭代,从而实现用户数量爆炸性增长,如“被黑客操纵”一般神奇。

让人信服的是,他不仅提出了这个理论,还亲自实现了自己的方法。他在 Dropbox 任职时,曾经用一年的时间把用户的基数和使用频率提高了500%。

实际上,在他提出增长黑客理论之前,已经利用这套方法,帮助 Uproar、LogMeIn 等很多公司实现了用户爆发增长,并且成功 IPO。

【增长黑客之父 Sean Ellis】

以下是由雷锋网收录的 Sean Ellis 的演讲全文。

大家好,我是 Sean Ellis,今天跟大家分享的内容是增长黑客式成功,也就是如何用增长黑客的方法来创造爆炸式的增长。

在进入演讲之前,我要先跟大家介绍一下我的背景。我在两家公司工作过,从完全没有用户的时候一直到这个公司在纳斯达克上市,我这样的经历的好处就是:我经历了一个公司从创业的初期,从零开始。比如说我在 LogMeIn 的时候,它是从一无所有的白手起家,到后来 IPO 上市。在这两家的公司经验中,让我认识到在这十年里最重要的时期就是两家公司的第一年。所以在这十年间,我只有其中的两年是非常非常重要的,这给了我非常重要的一个经验。

从那之后我就决定我要去到不同的公司,在每一个公司只待很短的一段时间,所以后来去了Dropbox,当时在 Dropbox 只有八个员工。那个时候我跟CEO每周会见两次,去讨论公司的增长。六个月之后我又去了另外一家公司,之后又去其它的公司。现在我有了自己的公司: GrowthHackers.com。

在这些不同公司的经历让我认识到,增长其实是一个呈金字塔式的模式。

首先你需要一个产品,如果你没有一个大家喜欢的产品,那你就很难去实现增长。所以一切的前提是:必须要有一个非常好的产品,和市场相匹配,之后我会有详细的介绍。我们有了这样的产品之后,接下来就是要去传递我们的价值。我们要做的是“优化”我们价值的传递。在这个阶段之后我们就要开始聚焦怎么去扩大增长规模了,这个阶段就是在企业增长的后期要长期关注的一个阶段。

那什么是产品市场匹配呢?

这是在硅谷非常流行的一个概念,它意味着用户认为你的产品是必不可少的,是不可或缺的。如果他们不这么认为的话你可能就没有足够的潜力。我据此就设计了一个非常简单的问题,如果你觉得你没有办法再使用这个产品了,你会有什么样的感受?

可能有的人会回答非常非常失望,我就认为这样的用户是我们的忠实用户;

他说有一点失望,或者是不失望;

甚至有的人说无所谓,就意味着这个产品的潜力不够了。

如果非常失望的比例达到将近 40%,就意味着这个业务是非常值得去增长的。那如果不到 40% 的话,可能这个产品的潜力就远远不够了。

而且我们要去看不同人群的说法,例如要去看女性群体是怎么认为的,男性是怎么认为的,学生是怎么认为的,年轻人是怎么认为的。如果我们没有达到40%的话,也不用放弃,因为我们不用在企业的初期就去非常关注迅速的增长,因为我们还在完善我们的产品;相反如果在企业的后期,如果增长停滞的话,这可能就意味着我们的产品出现了问题。

接下来,就要去优化我们价值的传递。

我到这些不同的公司的时候,其实很难预测要花多长时间才能创造价值。因为要让你的产品变得不可或缺,你要认识到你有其它竞争者,所以我们的时间是非常少的,必须要把握住机会,迅速的行动。

我们必须要非常充分地了解:

我们的价值是什么?

谁认为我们的价值是有价值的?

他们为什么觉得我们的产品有价值?

他们怎么使用我们的产品?

他们是怎么开始使用我们的产品的?

他们的期望是什么?

他们为什么要使用我们的产品?

所有的这些信息都能够帮助我们了解我们怎么样让更多的人来使用我们的产品。所以我们要关注他们怎么样成为我们的客户的,怎么样留下来的。为此我们要做不同的测试,让更多的人实现转化,让更多的人在初次体验产品的时候就有很好的体验,然后转化成我们的固定的用户。

【根据历史上的产品来看,最优的市场窗口往往很短】

我会花两三个月的时间来优化这个过程,之后这个公司基本上就已经准备好可以去扩大增长规模,可能对有的公司来说这个时间会花得更长一点,但是我们要尽可能地保证这个阶段花的时间越少越好,能够尽快的跨越这个阶段。

接下来就是:跨越增长。

如果你的产品没有人喜欢,可能就会非常的让人气馁,所以我们要保证在用户第一次使用这个产品的时候就能够有很好的体验,之后可能就会增长比较顺利。但是问题是可能增长会变得越来越困难,因为所有的公司都在致力于增长,所有的公司都在投入大量的金钱去寻找增长的方式。所以每天都会有新的机会出现,但是他们(机会)的有效期是非常短的,很快一个方法可能就不再适用了,你就必须要去找到新的方法,新的机会。

我可能刚刚一直在跟大家灌输一些比较负面的,说比较困难,但是事实的确如此,比如说如果你在转化上有问题的话,比如说有用户进来,他们对你的产品感兴趣,但是他们发现很难用,他们不了解你的产品的核心价值是什么,所以他们可能就没有办法去购买你的产品,所以在这个渠道上可能就没有办法有足够的竞争力,但如果你能够让用户去到你的网站,那可能你就成功了一半了。

即便是非常困难,但是仍然有些企业实现了非常高速的发展。我知道有的中国公司也是这样,比如说 Uber 可以说是在美国增长最快的公司,但是在中国没有打败滴滴。所以我觉得我去看这些不同的中国公司的情况,我发现成功的公司在增长的做法其实是非常类似的,例如:他们都在5到10年前就创立了这个增长团队。

我接下来就跟大家分享一下他们是怎么去成立增长团队的。

如果你有了增长团队之后,你怎么样去组织工作;如果你没有增长团队,你怎么样去着手成立一个增长团队。在过去几年我都在跟这些顶尖的怎样团队进行交流,所以这里要跟大家分享一下这些共同的最佳做法。

    我吸取到了一个最为重要的经验就是:“测试”非常重要。测试能够驱动增长,因为如果我们不去测试的话就无法确定这个想法能否可行。所以我们要尽量的去多做测试。去确定什么是有用的,什么是没有用的。比如说推特他们曾经获得非常快速的发展,但是很快这个增长停滞了。在2010年这个公司成立非常初期的时候,他们出现了增长停滞之后,就成立了一个新的团队。有一个新的产品 VP 进来。他进来之后说: “我们的测试量不够。我们只是几个月做几次测试。这太少了,我们必须每周做十次测试。”他们做了这个改变之后就更快地发现问题,增长速度果然恢复了。

【启动高频测试之后,用户增长速度迅速增加】

在我的公司也有类似的经验。我们也有增长停滞期,我就发现我们的测试量不够。所以我告诉我们的团队必须每周保证三次的测试,我们做了这样的改动之后,我们的增长也是又重新上升了。所以要首先认识到一点:测试能够驱动增长。

而且测试是由增长团队来实施的,增长团队本身也存在一个优化的过程。增长团队应该包括哪些角色呢?首先我们应该弄清楚有哪些人,必须要有的一个人就是增长负责人,他可能是增长的VP或者是产品经理,总之是一个能够领导增长团队的人。而且他能够去管理我们的测试流程,要告诉团队有足够的测试量,而且保证测试是有效的。

往往这样的一个增长的负责人,就是专门为了负责这个测试的环节才加入这个团队的。我们往往在这个团队里设立目标,我昨天就有讲到这一点:目标是非常重要的。今天不会去重复目标的重要性,但是目标是非常重要的,而且是正确的目标是非常重要的。我们对每一个具体的目标都应该有一个负责人,这样的负责人应该是有企业家精神的,他必须要非常专注的实现这个目标,而且能够非常紧密的跟踪这个目标的进度。而且他会越来越了解实现这个目标的方式,团队的其他人也都能够帮助他去做测试,帮助他实现这个目标。

我们要实现这个目标,就要去分析我们面临的情况,我们有什么问题,然后提出想法,提出可以解决我们这个问题的想法。然后排列一个优先级,先去测试哪一个想法,后去测试哪一个想法;然后进行测试,再进行分析。

在目标上,我们可以讲的内容是很多的,但是关键的一点就是我们要认识到,要有正确的目标。

一个正确的目标应该是有高影响力的目标,比如说你有 50% 的潜在用户都不会去注册。这么高比例的潜在用户都不会注册,说明你需要去关注这个问题。比如说,微信可能是你们很大的一个潜在用户的来源。但如果你没有通过这个渠道获得很多的用户的话,那你可能就需要设立一个目标,那就是我们怎么样增加从微信过去的客户量。

我们首先需要分析数据。

我们要去细化数据,比如说有多少人进入了这个页面,但是有多少人没有在下载,有哪些人下载了,对于那些没有下载的人你要分析原因,你要摸清这个产品的情况,了解这个情况背后的原因。比如说用户需要的是什么,用户用你的产品是为了什么目的,他们为什么使用呢?是因为你的产品是免费的,还是因为别的原因,你越是了解这个情况越是能够推出好的想法来实现这个目标。

接下来一个重要的方面就是提出想法,也就是解决问题的过程。

我们一旦了解了用户面临的问题之后,我们就可以着手解决这个问题了。我们可以每周都召开头脑风暴会议,或者说我们去跑步的时候,或者说在上下楼梯的时候可能都会想这个问题,会有新的想法出现。我就非常鼓励我团队的每一个成员都能去提出他们的想法。并不仅仅是一个目标的负责人,或者这个团队的领导者去提出想法,而是所有的人都应该参与进来。如果你能够鼓励所有人都参与进来的话你会惊讶的发现他们能够提出非常好的想法。

在提出想法的时候我们不应该仅仅只是拍拍脑门提出一来个想法,我们必须要把它树立为一个科学的过程。所以我们要有一个文档去记录具体的想法是什么,我们的假设是什么,有哪些既有的证据表明这样的想法可能是成立的。

比如说你是否做了一些调研,比如说你做了一些用户的调研,你需要对这个想法进行一个打分。我们有这样的几个标准:

首先你要考虑它的影响力,就是这个想法它对于我们的业务来说是很重要的呢,还是一般重要的。比如说我们要用微信来推进增长,那我们可能就要首先确定这样的一个方法对我们来说是不是至关重要的。比如说它能否给我们每天一万个新的用户。这个打分是1到10分,如果是10分的话,说明它对你公司的增长是有非常大的影响的,如果只是两三分的话,可能这个影响力就稍微弱一些了。所以它的打分是1到10分。

第二个标准也就是信心,你是否确定这个想法能够有效,也是1到10分的打分,10分表明你有数够的数据说明这个想法有效。

接下来就是它实施的难易程度,在Growth  Hacker这个网站上我们做一个测试,我们一致认为影响力得分数是很难预测的。曾经我们团队有个人提出说获得用户 email 很重要,因为我们每周都会发送 email 让用户来注册。如果我们把输入邮箱的端口移到我们的主页上面的话,我们可以收集到更多的邮箱。我们当时猜想这个影响力是4,但是我们测试以后,发现收到的邮箱数量增长了700%,所以它的影响力应该是10分。你永远无法预测到底什么有用,什么没用。有的时候我们只需要有10分钟做一个测试,那为什么不去做呢,也许它就可以促进增长,所以你做的测试越多,你就可以找到更好的方法去进行企业的增长。

增长它应该是建立在一个有用的东西的基础上的,当我们进行这个 email 的测试的时候,我们把输入邮箱栏放到上面,让更多的人进行了注册。我们就想如果我们可以让他们在输入自己的邮箱以后有第二步,就是让他们来直接创造一个帐号,来加入我们这个黑客增长的社区。所以我们也进行了这样的一个测试,通过这个方法我们让注册率增长了22%,我认为这是非常神奇的。

再比如说Dropbox,他们的页面上可以看到很多测试的元素,比如说“升级键”就表明这是他们的收入测试,这说明说大家是否想要了解更多,如果他们选择是的话,这其实是他们留存测试的一个结果。你一点击它就会出现把你的照片放进Dropbox,如果你把你的照片放在 Dropbox 的话你就更加有可能留存下来,你用的空间越多他收你的钱就越多。

一旦你有了想法之后,给这些想法进行优先分级就非常重要了,因此我们要每周开会。 我们会用30秒让大家阐释为什么你这个想法最好,我们要不要做这个测试。这种会议是非常重要的一个部分。

如何开这样的会议呢?

首先我们会看一下整体的增长情况,这就是我们每周会议的第一项。然后看一下目前我们其他 KPI 的情况,比如说我们是否有了更多的用户,或者说大家在我们这个产品上花的时间是不是越来越多。所以前15分钟我们讨论一下总体的增长。

然后我们就开始去讨论一些非常具体的目标,我们是否找到了好的增长机会。因为每个人都有负责一个具体的目标,我们可以从他们这了解一些比较具体的目标进行情况。我们是否有获取到什么经验。

然后我们要看一下我们之前所计划的测试是否全部进行过了。如果这个测试我们没有做,我们要找出原因是否是因为我们的设计师或者是其它开发者没有到位等等。如果我们找到原因那我们就不要去再做测试了,而去找到能够解决这个问题的人,比如说设计师等等。

我们要在最后确定下我们到底要做什么,这些都是建立在前面的测试之上的。你想做测试的话,肯定都想要做得更快,效率更高。你要找出之前的测试哪些是有用的,哪些是没用的,如果这个测试它证实是有用的话,你在之后的测试当中可以一直继续做这方面的测试。但是如果这个测试没用的话你必须要吸取其中的教训,了解原因,下次测试的时候避免犯同样的错误。

负责分析的人一般都是能够获得更多想法的人,因为他每天都在跟数据打交道,所以他非常的清楚。你跟数据打交道的时间越多,你获取的想法也就越多。这样的人能够更加预测出哪样的测试更容易成功,这样也可以帮助公司增长很快。

我认为一个增长很快的公司,非常重要的一点就是必须要有一个促进增长的团队。很多人问我说,如果必须要做一件事,什么才能促进我的增长呢,真正的尚方宝剑就是你要有一个增长团队,加上你的黑客增长过程。这两者加起来其实就是一个魔法了,可以确保我们可以成功。当然了很重要的是你还要去做很多的测试,你做测试越多你成功的机率越大。

我回顾一下比较重要的东西,首先你要确保大家确实需要或者是喜欢你的产品,你再去做营销,大家为什么喜欢你的产品,要找到这个产品的核心价值。之后你就必须要设立一个非常远大的每周测试的目标,因为你要去做尽可能多的测试。为了做高质量的测试,你必须要有一个增长团队和一个增长过程。

只要你做到这些事情,你就会发现增长是可以加快,而且是可预测的,谢谢。

以下为专访内容,雷锋网做了不改变原意的删减。

Q:很多产品的运营人员,他们最大的问题是不会运用数据。怎样才能快速地掌握运用数据的方法呢?

Sean Ellis:

互联网上的数据非常多,量非常大,我们要在数据终找到两个关键点:

一个就是 标准数据,就是激活量或者是用户存留量。

另一个就是我们通过进行大量的测试,找到的 关键数据

我们可以通过数据监测,关键指标表现,来观测是不是在增长情况中有骤降的情况。检测数据的增长是否健康是否良好,然后保持它的稳定性。通过我们不停的实验和测试,来提高我们的技能。

Q:要使用“增长黑客”的手段,需要企业的领导者有怎样的特质呢?

Sean Ellis:

中国的传统公司理念受到一些文化的限制,对风险的承受能力不强。其实,最成功的增长黑客,它也是经历最多失败的人。例如: 测试了100件事,有25个想法是正确的,虽然失败了很多次,但也收获了25个好的想法。

也就是说管理层要有接受风险的能力,团队人员也要相信他。

我曾经买了一家公司,利用“增长黑客”的方法来经营。但是事实证明这有很大的风险,我甚至把已有的稳定业绩都毁掉了。但是,我告诉我的投资人这很正常。因为尝试就意味着风险。但是,在持续运用这个方法,并且改进之后,就有了业务的激增。

这个骤降的过程对企业领导者来说很有挑战,但是总的来说,企业家就是要有承受风险的能力。

Q:增长黑客,最成功的案例可能是 Uber 和亚马逊,但是 Uber 在中国被滴滴合并,亚马逊也不如中国的阿里巴巴和京东,怎么解释这个现象?

Sean Ellis:

有一个词叫“主场优势”。

我觉得问题最大的就是他们低估了对手对市场的了解。文化和顾客的意识在每个地方都是不同的。增长黑客的流程、意识和理念是全世界通用的。 如果拥有对中国市场的深刻了解,再运用上增长黑客的理念,就会比外国的公司增长的更快。例如 Facebook,他们的市值非常大,但是从没有花一分钱在市场营销这方面,因为他们完全采用了增长黑客的方法和理念。

我觉得增长黑客的方法在中国并不需要所谓的“微调”。因为我们的核心还是用科学方法进行的数据分析,这个过程在每个国家都应该是一样的。我们针对这个市场增长的答案是不同的,但是科学分析数据的过程是一样的。

Q:你有没有看到哪些中国公司在数据增长方面做得非常优秀?

Sean Ellis:

我对中国公司并不是特别了解,但是这几天遇到的一些公司都让我感到惊喜。

因为利用“增长黑客”这种模式取得成功,靠的不是天马行空的想法,而是有固定的模式通过不断测验数据才成功的。而我发现 中国文化中,存在着非常勤勉和谦虚的一面。很多已经很成功的 CEO 都在积极寻求怎样发展得更好。而相反,在硅谷很多公司发展到一定规模之后,他们会骄傲自满,认为没有人可以指导他们。

但是,对于中国公司来说, 也许更需要用开放心态来来迎接风险。刚才在会场,很多害羞的人不敢举手,因为害怕尴尬。但是这样在规避风险的同时,也失去了交流的机会。

利用增长黑客,首先最好是高层 CEO 要有这样的想法,然后推广,让你的员工也接受。传统的商业模式部门和部门之间不交叉,各司其职。但是黑客增长之间需要各部门需要融合,需要交流,这样就需要 CEO 有这样的想法和理念,才能够更好地推动实施。

Q:你刚才提到增长黑客过程中要经历很多失败,能不能讲讲你遇到的难忘的失败经历?

Sean  Ellis:

我们肯定会经历很多测试,但是这个失败也不是很惨痛的失败,是一些小的测试。

比如:有十个内容都可以在同一个按钮上实现,但是我们要一一测试哪个效果会更好。这样我们就要测试十次,显然也会失败九次。因为我们的测试量很大,所以失败的次数也很多,是这样的一个过程。

我昨天也分享了另一个例子:

有一个应用,需要用户填写基本信息,然后在页面下方有下载入口。但是, 有 100 个人都填了这些信息,但是 90 个人都不愿意点击下载。


我们进行了无数测试,把这个下载的按钮放大,当然不能太大,否则就太恐怖了;或者变成红色的;或者提醒大家说是下载是绝对安全的。但就是有 90% 的人不愿意下载。


最后,我们根据用户在信息页留下的邮箱去询问用户。可能只有1%的用户回信,但是这也足够了。他们反馈居然说: 不相信这个应用是免费下载的。


于是我们就在页面下方设置了两个按钮,一个是收费按钮,一个是免费按钮,并且在免费按钮旁边打了一个大大的推荐标志。这样以来, 只有 70% 的用户不愿意下载了,虽然这个数据仍然不好,但是却已经好多了。

Q:最近印象笔记表示,为了更好地促进用户体验改进,需要读取客户的笔记内容。对于增长黑客和保护隐私之间的矛盾,你怎么看?

Sean  Ellis:

很多公司也有类似的方法,但是他们会 给用户一个选择,比如说你是否愿意给我们公司分享你的数据。如果你愿意,我们可以共享,把别的公司的优秀内容也给你分享。如果你选择不分享,你也得不到这些,所以这是个交换的过程中。

其实我感觉印象笔记已经在读取到我的笔记了,因为他推荐的文章都是和我笔记相关的内容。我觉得这个方法是险招,因为这不一定是用户的需求。

Q:是否存在一种情况,利用增长黑客方法在短期大幅提升了用户量,但是使用了一些长期来看对用户量有损伤的方法?

Sean  Ellis:

美国有一家公司,他们只是盲目地追求注册量,疯涨的注册量也带来了快速的消亡和衰退。

我在演讲中也提到,黑客增长的核心还是找到用户最需要的价值和核心体验,让核心体验触及到更需要这种价值和功能的用户,这才是可持续的发展方式。

增长黑客要寻求长的发展,就要用科学合理的分析来做,如果想要获得激增的想法,那就不会带来很好的收益。说到底, 一个好的产品,最好是能够通过口碑相传,而增长黑客的作用,是可以让它能够有更快的发展和二次增长的动力。

(文/史中 雷锋网)

分析师预测:增强现实设备将会取代iPhone

$
0
0

  Gene Munster 是一位在华尔街知名度相当高的苹果分析师,但是他的预测报告向来不怎么样。比如,这位老兄曾坚持多年预测苹果“很快”会推出传说中的 iTV。然而三年又三年,这么多年过去了一个苹果电视的零件都看不到影子。好在,Gene Munster 已经决定不当分析师了,所以在离职之前,他有一番语重心长的话要对苹果说。


  威锋网此前已经报道过,Munster 认为苹果的未来五年应该把重心放在服务这一版块。现在这名分析师又补充了他的建议。Munster 表示,以目前的趋势来看,增强现实技术(AR)迟早会成为主流,届时支持 AR 技术的可穿戴设备将有可能会取代现在仍风光无限的 iPhone。所以,他认为苹果应该趁早下手。

  “为手机添加各种各样的传感器,更换手机材质等做法只能在短期内找到机会。长久来说,苹果应该加大对 AR 可穿戴设备的研发,因为 iPhone 迟早会被取代。”据了解,Munster 离开所在的投资机构 Piper Jaffray 之后,将会自立门户,打造属于自己的风险投资公司,并从事与 AR/VR 解决方案、人工智能等先进技术有关的工作。

阅读全文


从 HTML 提取文本的 7 个工具

$
0
0

本文包括了为初学者和小项目而设计的简单工具,还有需要一定的编码知识,旨在用于更大,更困难的任务的高级工具。

收集电子邮件地址、竞争分析、网站检查、定价分析和客户数据收集 — 这些可能只是你需要从 HTML 文档中提取文本和其他数据的几个原因。不幸的是,手动做这种事是很痛苦的而且效率很低,在某些情况下甚至不可能实现。幸运的是,现在有各种各样的工具可以实现这些需求。下面的 7 个工具包括了由为初学者和小项目而设计的非常简单的工具到需要一定的编码知识,旨在用于更大,更困难的任务的高级工具。

Iconico HTML 文本提取器 (Iconico HTML Text Extractor)

试想一下,你正在浏览竞争对手的网站,然后想提取出文本内容,又或是想看看页面背后的 HTML 代码。但十分不幸,你发现右键被禁用了,复制和粘贴也是如此。现在许多 Web 开发人员正在采取措施禁用查看源代码,否则锁定其页面。幸运的是,Iconico 有一个 HTML 文本提取器,你可以用来绕过所有的这些限制,而且这个产品非常易于使用。你可以高亮和复制文本,提取功能的运行使用轻易得像上网一样。

UiPath

UIPath 有一套自动化过程工具,里面包含了一个 Web 内容抓取实用程序。要使用该工具,并获得所需的几乎任何数据十分简单 — 只需打开页面,转到工具中的设计菜单,然后单击“网络抓取(web scraping)”。 除了网络抓取工具,屏幕抓取工具允许您从网页中拉取任何内容。 使用这两种工具意味着您可以从任何网页抓取文本,表格数据和其他相关信息。

Mozenda

Mozenda 允许用户提取 Web数据,并将该信息导出到各种智能商务工具。它不仅可以提取文本内容,还可以从 PDF 文件中提取出图像,文件和内容。然后,你可以将这些数据导出到 XML 文件,CSV 文件,JSON 或者可以选择使用 API。 提取和导出数据后,就可以使用 BI 工具进行分析和报告。

HTMLtoText

这款在线工具可以从 HTML 源代码中提取文本,甚至只是一个 URL 也可以。你所需要做的只是复制和粘贴,提供一个 URL 或者上传文件。 单击选项按钮,让工具知道你需要的输出格式和一些其他的细节,然后点击转换,你将获得你需要的文本信息。

(还有一个类似的工具 — www.htmlnest.com/htmltotext.aspx

Octoparse

Octoparse 的特征是它提供的是“点击”用户界面。即便是没有过编码知识的用户也可以从网站提取数据并将其发送到各种文件格式。这个工具包括从页面中提取电子邮件地址,从招聘板上提取职位列表等功能。该工具适用于动态和静态网页以及云采集(配置好采集任务关机也能采集数据)。它提供了一个免费版本,对于大多数使用场景应该足够应付,而付费版本则有更多丰富的功能。

如果你是为了进行竞争分析而抓取网站,可能会因为此活动而被禁止。因为 Octoparse 包含一个循环识别你的 IP 地址的功能,并能通过你的 IP 禁止你使用。

Scrapy

这个免费的开源工具使用网络爬虫从网站提取信息,使用这个工具需要一些高级技能和编码知识。但如果你愿意以你的方式去学习使用它,Scrapy 是抓取大型 Web 项目的理想选择。该工具已被 CareerBuilder 和其他主要品牌使用。因为它是一个开源工具,所以这为用户提供了很多良好的社区支持。

Kimono

Kimono 是一个免费的工具,从网页获取非结构化数据,并将该信息提取为具有 XML 文件的结构化格式。该工具可以交互使用,也可以创建计划作业以在特定时间提取你需要的数据。你可以从搜索引擎结果、网页、甚至幻灯片演示中提取数据。最重要的是,当你设置好每个工作流时,Kimono 会创建一个 API。这意味着当你返回到网站以提取更多数据时,不必再重新造轮子。

结论

如果你遇到需要从一个或多个网页中提取非结构化数据的任务,那么此列表中至少有一个工具应该包含你需要的解决方案。而且无论你的期望价格是什么,你都应该能找到你所需要的工具。了解清楚然后决定哪个是最适合你的。要知道,大数据在企业蓬勃发展中的重要性,并且收集所需信息的能力对于你来说也是至关重要。

从 HTML 提取文本的 7 个工具,首发于 文章 - 伯乐在线

(收藏)Spring Security笔记:解决CsrfFilter与Rest服务Post方式的矛盾

$
0
0
基于Spring Security+Spring MVC的web应用,为了防止跨站提交攻击,通常会配置csrf,即:

1     <http ...>
2         ...
3         <csrf />       
4     </http>
如果应用中有Post方式访问的Rest服务(参考下面的代码),会很不幸的发现,所有POST方式请求的服务会调用失败。

复制代码
1     @RequestMapping(value = "/user/create", method = RequestMethod.POST)
2     @ResponseBody
3     public UserInfo createUser(@RequestBody(required = true) UserInfo user,
4             HttpServletRequest request, HttpServletResponse response)
5             throws Exception {
6         ...
7     }
复制代码
原因在于:启用csrf后,所有http请求都被会CsrfFilter拦截,而CsrfFilter中有一个私有类DefaultRequiresCsrfMatcher

复制代码
1     private static final class DefaultRequiresCsrfMatcher implements RequestMatcher {
2         private Pattern allowedMethods = Pattern.compile("^(GET|HEAD|TRACE|OPTIONS)$");
3
4         /* (non-Javadoc)
5          * @see org.springframework.security.web.util.matcher.RequestMatcher#matches(javax.servlet.http.HttpServletRequest)
6          */
7         public boolean matches(HttpServletRequest request) {
8             return !allowedMethods.matcher(request.getMethod()).matches();
9         }
10     }
复制代码
从这段源码可以发现,POST方法被排除在外了,也就是说只有GET|HEAD|TRACE|OPTIONS这4类方法会被放行,其它Method的http请求,都要验证_csrf的token是否正确,而通常post方式调用rest服务时,又没有_csrf的token,所以校验失败。

解决方法:自己弄一个Matcher

复制代码
1 package com.cnblogs.yjmyzz.utils;
2
3 import java.util.List;
4 import java.util.regex.Pattern;
5
6 import javax.servlet.http.HttpServletRequest;
7
8 import org.springframework.security.web.util.matcher.RequestMatcher;
9
10 public class CsrfSecurityRequestMatcher implements RequestMatcher {
11     private Pattern allowedMethods = Pattern
12             .compile("^(GET|HEAD|TRACE|OPTIONS)$");
13
14     public boolean matches(HttpServletRequest request) {
15
16         if (execludeUrls != null && execludeUrls.size() > 0) {
17             String servletPath = request.getServletPath();
18             for (String url : execludeUrls) {
19                 if (servletPath.contains(url)) {
20                     return false;
21                 }
22             }
23         }
24         return !allowedMethods.matcher(request.getMethod()).matches();
25     }
26
27     /**
28      * 需要排除的url列表
29      */
30     private List<String> execludeUrls;
31
32     public List<String> getExecludeUrls() {
33         return execludeUrls;
34     }
35
36     public void setExecludeUrls(List<String> execludeUrls) {
37         this.execludeUrls = execludeUrls;
38     }
39 }
复制代码
这里添加了一个属性execludeUrls,允许人为排除哪些url。

然后在配置文件里,这样修改:

复制代码
1     <http entry-point-ref="loginEntryPoint" use-expressions="true">
2         ...
3         <intercept-url pattern="/rest/**" access="permitAll" />
4         ...
5         <csrf request-matcher-ref="csrfSecurityRequestMatcher"/>       
6     </http>
7    
8     <beans:bean id="csrfSecurityRequestMatcher" class="com.cnblogs.yjmyzz.utils.CsrfSecurityRequestMatcher">
9         <beans:property name="execludeUrls">
10             <beans:list>
11                 <beans:value>/rest/</beans:value>
12             </beans:list>
13         </beans:property>
14     </beans:bean>
复制代码
这里约定所有/rest/开头的都是Rest服务地址,上面的配置就把/rest/排除在csrf验证的范围之外了.

已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



基于Twemproxy的Redis集群方案

$
0
0

概述

由于单台redis服务器的内存管理能力有限,使用过大内存redis服务器的性能急剧下降,且服务器发生故障将直接影响大面积业务。为了获取更好的缓存性能及扩展型,我们将需要搭建redis集群来满足需求。因redis 3.0 beta支持的集群功能不适合生产环境的使用,所以我们采用twitter正在使用的twemproxy来搭建redis缓存服务器集群,目前用户包括Pinterest、Tumblr、Twitter、Vine、Kiip、Wuaki.tv、Wanelo、Kontera、Wikimedia、Bright、56.com、Snapchat、Digg、Gawkermedia、3scale.net等。

Twemproxy是memcached和redis协议的代理服务器,并能有效减少大量连接对redis服务器的性能影响,它提供的主要特性如下:

image

 

 

集群架构

image

 

安装Redis

有三台服务器,一台COS1安装twemproxy,另外两台COS2,COS3安装redis。

 

  1. 下载最新安装包:redis-2.8.9.tar.gz , tcl-8.5.7-6.el6.x86_64.rpm ,nutcracker-0.3.0.tar.gz
  2. image
  3. 安装必要组件rpm:
    [root@COS2 redis-2.8.9]# yum install gcc
    [root@COS2 src]# rpm -ivh tcl-8.5.7-6.el6.x86_64.rpm
  4. 安装Redis:
    复制代码
    [root@COS2 src]# tar xvf redis-2.8.9.tar.gz
    [root@COS2 src]# cd redis-2.8.9
    [root@COS2 redis-2.8.9]# make
    …
    Hint: To run 'make test' is a good idea ;)
    make[1]: Leaving directory `/usr/local/src/redis-2.8.9/src'
    
    [root@COS2 redis-2.8.9]# make test
    All tests passed without errors!
    
    Cleanup: may take some time... OK
    make[1]: Leaving directory `/usr/local/src/redis-2.8.9/src'
    [root@COS2 redis-2.8.9]# make install
    [root@COS2 redis-2.8.9]# cd /usr/local/bin/
    [root@COS2 bin]# ll
    total 13908
    -rwxr-xr-x. 1 root root 4170264 Apr 26 11:51 redis-benchmark
    -rwxr-xr-x. 1 root root   22185 Apr 26 11:51 redis-check-aof
    -rwxr-xr-x. 1 root root   45419 Apr 26 11:51 redis-check-dump
    -rwxr-xr-x. 1 root root 4263471 Apr 26 11:51 redis-cli
    -rwxr-xr-x. 1 root root 5726791 Apr 26 11:51 redis-server
    复制代码
  5. 编辑redis配置文件:
    复制代码
    [root@COS2 redis-2.8.9]# cp redis.conf /etc/
    [root@COS2 redis-2.8.9]# vim /etc/red
    redhat-release  redis.conf      
    [root@COS2 redis-2.8.9]# vim /etc/redis.conf
    
    把里面的
    daemonize no  修改成 daemonize yes
    复制代码
  6. 启动redis服务:
    [root@COS2 redis-2.8.9]# redis-server /etc/redis.conf
  7. 测试redis服务:
    [root@COS2 redis-2.8.9]# redis-cli 
    127.0.0.1:6379> set kin kin
    OK
    127.0.0.1:6379> get kin
  8. 同样的步骤安装其他redis服务器。

 

 

安装twemproxy

  1. 安装twemproxy:
    [root@COS1 src]# tar xvf nutcracker-0.3.0.tar.gz
    [root@COS1 nutcracker-0.3.0]# cd nutcracker-0.3.0
    [root@COS1 src]#./configure 
    [root@COS1 nutcracker-0.3.0]# make && make install
  2. 编辑配置文件:
    复制代码
    [root@COS1 conf]# cd /usr/local/src/nutcracker-0.3.0/conf
    [root@COS1 conf]# cp nutcracker.yml /etc/
    [root@COS1 conf]# vim /etc/nutcracker.yml
    alpha:
      listen: 0.0.0.0:22121
      hash: fnv1a_64
      distribution: ketama
      auto_eject_hosts: true
      redis: true
      server_retry_timeout: 2000
      server_failure_limit: 1
      servers: --两台redis服务器的地址和端口
       - 10.23.22.240:6379:1   
       - 10.23.22.241:6379:1
    复制代码
  3. 测试配置文件:
    [root@COS1 nutcracker-0.3.0]# nutcracker -t /etc/nutcracker.yml 
    nutcracker: configuration file 'conf/nutcracker.yml' syntax is ok
  4. 启动twemproxy:
    复制代码
    [root@COS1 nutcracker-0.3.0]# nutcracker  --help
    This is nutcracker-0.3.0
    
    Usage: nutcracker [-?hVdDt] [-v verbosity level] [-o output file]
                      [-c conf file] [-s stats port] [-a stats addr]
                      [-i stats interval] [-p pid file] [-m mbuf size]
    
    Options:
      -h, --help             : this help                           
      -V, --version          : show version and exit                 
      -t, --test-conf        : test configuration for syntax errors and exit 
      -d, --daemonize      : run as a daemon                    
      -D, --describe-stats   : print stats description and exit
      -v, --verbosity=N      : set logging level (default: 5, min: 0, max: 11)
      -o, --output=S         : set logging file (default: stderr)
      -c, --conf-file=S      : set configuration file (default: conf/nutcracker.yml) #配置
      -s, --stats-port=N     : set stats monitoring port (default: 22222)
      -a, --stats-addr=S     : set stats monitoring ip (default: 0.0.0.0)
      -i, --stats-interval=N : set stats aggregation interval in msec (default: 30000 msec)
      -p, --pid-file=S       : set pid file (default: off)
      -m, --mbuf-size=N      : set size of mbuf chunk in bytes (default: 16384 bytes)
    [root@COS1 nutcracker-0.3.0]# nutcracker -d -c /etc/nutcracker.yml
    [root@COS1 nutcracker-0.3.0]# ps -ef|grep nutcracker
    root     15358     1  0 02:40 ?        00:00:00 nutcracker -d -c /etc/nutcracker.yml
    复制代码
  5. 测试twemproxy:
    复制代码
    [root@COS1 ~]# redis-cli -p 22121
    127.0.0.1:22121> get kin"kin"
    127.0.0.1:22121> set kin king
    OK
    127.0.0.1:22121> get kin"king"
    复制代码

 

 

 

 

性能测试

这里使用redis自带的redis-benchmark进行简单的性能测试,测试结果如下:

  1. Set测试:
    1. 通过twemproxy测试:
      [root@COS1 src]# redis-benchmark -h 10.23.22.240 -p 22121 -c 100 -t set -d 100 -l –q
      SET: 38167.94 requests per second
    2. 直接对后端redis测试:
      [root@COS2 ~]# redis-benchmark -h 10.23.22.241 -p 6379 -c 100 -t set -d 100 -l –q
      SET: 53191.49 requests per second
  2. Get测试:
    1. 通过twemproxy测试:
      [root@COS1 src]# redis-benchmark -h 10.23.22.240 -p 22121 -c 100 -t get -d 100 -l -q
      GET: 37453.18 requests per second
    2. 直接对后端redis测试:
      [root@COS2 ~]# redis-benchmark -h 10.23.22.241 -p 6379 -c 100 -t get -d 100 -l -q
      GET: 62111.80 requests per second
  3. 查看键值分布:
    [root@COS2 ~]# redis-cli info|grep db0
    db0:keys=51483,expires=0,avg_ttl=0
    
    [root@COS3 ~]# redis-cli info|grep db0
    db0:keys=48525,expires=0,avg_ttl=0

测试结果:以基本的set get命令通过twemproxy性能有所下降;通过twemproxy分布基本平均。测试数据以业务测试为准。



已有 0人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



一个妹子的自白:为何更爱SE而不是7 Plus

$
0
0

  威锋网讯,有些用户喜欢大屏手机,有些用户则喜欢小屏手机,萝卜青菜,各有所爱,这并没有错。选择最适合自己的手机,才是最重要的。iPhone 7 Plus 可能很强大,但还是有人在 3 个月后用回 iPhone SE 了,她就是 iMore 的编辑 Lory Gil,至于原因是什么,接下来就来听听她是怎么说的吧。


  我喜欢 4 英寸的 iPhone,尽管 4.7 和 5.5 英寸的 iPhone 设备在很多情况下都很好。但对于部分人来说,他们依然希望自己的手机能够轻松地塞到裤子后面的口袋中,并且能够毫不费力地进行单手操作。

  为什么 iPhone 7 Plus 使我动摇?

  一款大屏手机想要说服我去用它,首先它需要足够特别,而 iPhone 7 Plus 正是这样的手机。哪方面吸引我?相机。

  iPhone 7 Plus 的相机相信大家都很清楚了,它配备了两个后置摄像头,同为 1200 万像素,其中一个是广角镜头,光圈 f/1.8;另一个是长焦镜头,光圈 f/2.8。因为双摄像头的存在,iPhone 7 Plus 支持两倍的光学变焦,并不是能让你的照片留下颗粒感的数码变焦。

  此外 iPhone 7 Plus 相机应用还支持了人像模式,它可以带来极其出色的背景虚化效果,尽管还不能说完全达到单反级别,但用智能手机能够拍出这样的效果已经是非常不错了。

  iPhone 7 Plus 还有很多值得一提的地方,例如广色域(DCI P3)、更好的扬声器以及 A10 Fusion 芯片。讲真,如果不是相机的话,我是不会更换我的 iPhone SE 的。

   使用 iPhone 7 Plus 的日常


   总结:香菇

  没错,长时间使用 iPhone 7 Plus 后发现的确“蓝瘦”。如果用双手举着横屏模式下的 iPhone 7 Plus 还好,但是谁又会一直让手机处于横屏模式呢?

  如果我查看邮件,又或者是在 Slack 上和同事进行交谈,我的手掌和手腕就会开始酸痛。然后我就只能将手机放在膝盖或桌面上,这样我的手才能得到休息。

  当我玩游戏的时候,我需要将无名指放在手机背面进行支撑。如果玩游戏超过 10 分钟,手指也会有疼痛感,因为它摩擦到了 Lightning 接口的边缘。同样地,右手小指也会出现类似的情况。

  可能你会觉得有点可笑,但这的确是我在日常使用中的感受。毕竟 iPhone 7 Plus 比我之前使用的 iPhone 要更大,更重。

   我应该继续还是离开

  需要指出的是,iPhone 7 Plus 有很多令人惊叹的功能是 iPhone SE 没有的。我喜欢 3D Touch,我喜欢 iPhone 7 Plus 的 Home 键,我喜欢它的高性能,我喜欢触觉反馈,当我看视频或玩游戏的时候我喜欢明亮的颜色和大屏,我喜欢立体扬声器的清晰声音,我喜欢不用斜视也能够看清一切的感觉。最重要的是,我喜欢相机,相机,相机(重要的事情说 3 遍)。

  不过,我不喜欢它放不进我的口袋,我不喜欢经常要拿着在手中,因此很担心经常会将它遗忘在桌子上。如果将它放在裤子后面的口袋,就不能坐下来,它也可能会从口袋中掉出来。而且用它我也不能单手玩《精灵宝可梦》,我也不喜欢长时间使用它所带来的疲劳感。

  当我使用 iPhone 7 Plus 3 个月之后,我发现大小对于移动手机来说真的很重要。我需要的是轻、小和单手易用的手机,显然 iPhone 7 Plus 不是我的菜。这也是我为什么用回 iPhone SE 的原因,当你读到这里的时候,我已经用完 iPhone SE 了。

  大屏幕,更明亮的色彩和更高速的性能就不需要吗?我已经有 9.7 英寸的 iPad Pro 了,在我看来,iPhone 7 Plus 的便携性和 9.7 英寸的 iPad Pro 是一样的,因为都只能放进包里。

   给你的建议

  如果你喜欢 4 英寸的 iPhone,但一直被周围的人煽动购买 iPhone 7 Plus,那么你需要认真想想:你为什么还在使用 4 英寸的 iPhone。

  如果答案是你的手比较小,担心 iPhone 7 Plus 太难握持,那么不妨先升级至 4.7 英寸的 iPhone 试试。

  如果你的答案是便携性(可以放进口袋),但又想升级到较新的 iPhone,那么不妨换个思路,例如买一个腰包,又或者是大一点的钱包。当然,有些裤子的口袋也是足够大的。

  如果你的答案是费用,那么你可以考虑一下上一代的产品,例如 iPhone 6s Plus,它也有很多功能是 4 英寸 iPhone 所不具备的,例如 3D Touch,更多的储存空间(最大 128GB,而 iPhone SE 最大只有 64GB),以及 500 万像素的前置摄像头。而且,它还比 iPhone 7 Plus 便宜不少。

  还是那句话,选择自己合适的手机,才是最重要的。至于性能或相机等因素,自己觉得够用就好。

阅读全文

埃森哲:2016零售业消费者研究(附下载)

$
0
0

报告下载:添加199IT官方微信【i199it】,回复关键词【2016零售业消费者研究】即可

近日,埃森哲发布了《2016零售业消费者研究——消费者在呼求,零售够“灵”》(Retail Consumer Research 2016)研究报告。我们的研究显示,千禧一代消费者将主导整个亚洲消费市场。因此,零售商和消费品企业必须积极采用数字解决方案,才能为千禧一代消费者提供其所需的互联、整合的购物体验。

为了完成《2016零售业消费者研究》报告,埃森哲共调研了来自13个国家的1万多名消费者。作为该项研究的一部分,埃森哲从中选取了来自中国和日本的746名千禧一代消费者,这些受访者在2015年第四季度曾在网上和实体店中购物。调研反馈者从面板数据中选择,并且经过了欧洲民意与市场调查协会(ESOMAR)的审核,严格遵守市场研究的各项国际准则。购物者样本均衡地分布在七个行业,分别为:服饰、消费电子产品、百货商场、折扣店、大众商店和大卖场、日用杂货品商店、药店和家装店。同时,样本还覆盖了不同性别、年龄、家庭收入水平和居住地区。本次调研从所有购物者中筛选出了经常使用互联网和智能手机的个人,其置信度为95%,误差范围±3.6%。

机遇就在眼前

 

埃森哲的分析显示,到2020年,亚太地区电子商务销售总额有望增长三倍,达到2.6万亿美元。同时,亚洲地区千禧人群的消费能力会超过以往任何一代人,到2020年,其可支配收入将增加至6万亿美元。届时,全球60%的千禧一代消费者将生活在亚洲,占本地区人口的45%以上。因此,零售商和消费品企业必须深入解读这一精通技术、实时互联的群体,充分挖掘潜藏的巨大机遇,牢牢把握这一强大的消费群体。

 

埃森哲消费品与服务业资深董事总经理特奥·科雷亚(Teo Correia)表示:“数字化正在改变全球消费品行业,并赋予消费者更多的选择权、洞察力和控制力。千禧一代消费者希望获得简单愉悦、根据其兴趣和生活方式量身定制的购物体验。他们变得越来越难以预测,并形成了更多细分消费群,同时他们还是强大品牌和互动购物体验的拥趸者。为了赢得其忠诚度,各品牌的当务之急就是利用数据驱动型的应用,为其提供简明而极具个性化的体验。”

 

千禧一代热衷移动购物

 

数字技术与服务正逐步成为消费者日常生活的组成部分。如今,亚洲地区拥有全球半数以上的智能手机用户,其中新加坡和澳大利亚的智能手机普及率均已超过80%,居世界首位。与此同时,亚洲地区千禧一代消费者平均每天使用智能手机达2.8个小时(即每年42.5天),他们中的四成以上曾通过智能手机购物。
埃森哲的分析表明,相较其他消费者群体,千禧一代对他人建议持更加开放的态度。零售商和消费品企业正努力通过个性化服务满足该群体需求,但前提是必须确保其方式能够为消费者所接受,例如:

 

•  为了获取更加个性化的体验,60%的受访中国和日本的千禧一代消费者允许零售商获取其个人信息,而整体消费群体中具有同样想法的比例仅为47%。
•  在实体门店中,77%的中国和日本千禧一代赞同用忠诚度积分和折扣券自动抵减商品价格,不过只有37%的受访者欢迎销售人员询问其近期购买记录。
•  61%的中日千禧一代希望通过网络收到他们正考虑购买商品的促销信息。

 

科雷亚补充道:“我们看到,成功的品牌正通过提升数据分析能力,着力打造个性化的客户体验,并从忠诚度、购买历史和人口地理特征等维度出发精准定价。他们越来越多地运用预测分析来提供定制产品服务,同时透过基于定位的服务,将自身紧密融合到消费者的生活方式当中。而企业制胜的关键则是在各个渠道与客户进行沟通,确保消费者自始至终获得心满意足的品牌体验。”
2016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000012016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000022016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000032016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000042016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000052016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000062016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000072016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000082016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000092016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000102016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000112016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000122016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000132016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000142016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_0000152016%e9%9b%b6%e5%94%ae%e4%b8%9a%e6%b6%88%e8%b4%b9%e8%80%85%e7%a0%94%e7%a9%b6_000016

报告下载:添加199IT官方微信【i199it】,回复关键词【2016零售业消费者研究】即可

您可能也喜欢的文章:

埃森哲:2014年中国消费者洞察洞察报告全篇(附下载)

埃森哲:调研发现消费者愿意为车联网额外付费

埃森哲:在互联新世界与数字消费者互动

埃森哲:2016年技术展望报告(附下载)

百度:移动互联时代消费者决策研究(附下载)
无觅

Google 和百度都公布了年度热搜榜,玩不了 Pokémon Go 的国人在关注什么?

$
0
0
作者: OD

又到了年终盘点的月份,世界上最有代表性的两个搜索引擎 Google 和百度,都接连发布了年度热搜榜。

在互联网时代,搜索是最能反映群体关注度的工具之一,即使是资讯 App 盛行的当下也不例外。我们来对比看看,生活在围墙内的中国网民这一年关注着什么,和全球人民有什么异同。

热词:小精灵热席卷全球,玩不了的中国民众更关心奥运和现实问题

屏幕快照 2016-12-18 19.14.37.png

Google 全球热搜词排名第一的是《Pokémon Go》,看来大家都忙着捉小精灵。而玩不了《Pokémon Go》的中国民众今年最关注里约奥运会。

pokemon-go-compilation_2058.0.0.jpg

Google 全球热搜词排行榜比较娱乐化,除了 iPhone 7, 特朗普和奥运,还有两部超级英雄电影、两位音乐界人士、以及一种彩票和一个贪食蛇游戏。

占据了年度热搜词第 9 名的 Slither.io 稍稍改造了贪食蛇这个传统游戏,变成联网的玩法,你需要边变长边躲避其他玩家,还有个当天的全球玩家排名榜。

屏幕快照 2016-12-18 11.44.32.png

百度十大关键词榜单比较现实,我们可以看到房价飙升、车牌摇号、营改增、疫苗安全、全面放开落户限制、反腐和全面二孩等非常接地气的名词,大家都很关心切身相关的问题。

人工智能和互联网金融也上榜了,可见这两个领域今年在中国有多火。

人物:不管全球还是中国,都很关注特朗普和希拉里

屏幕快照 2016-12-18 16.41.32.png

两个榜单共同点是,文体娱人士居多,参插着几个政治人物。Google 全球热搜人物几乎都是美国人物,而百度十大焦点人物榜单第一名是个韩国人。

由于今年是美国大选年,特朗普和希拉里分别占据了 Google 全球热搜人物的第一和第二。百度十大焦点人物榜单中,特朗普和希拉里也上榜了,可见中国民众对美国大选的关注度相当高,以至于网上有个段子:「美国大选日,中国人民终于实现了全民参政议政」。

20161105124443344.jpg

Google 全球热搜人物中,有一位 Steven Avery(史蒂芬·艾弗里)大家可能比较陌生。他曾经因「性侵犯」而服刑十八年,直到 DNA 证据证明罪犯另有其人才得以沉冤昭雪。

在向政府官员发起总金额 3600 万美元的索赔诉讼的时候,他又被控谋杀了 25 岁的女摄影师泰瑞莎 · 海尔贝克。Netflix 一部纪录片《制造杀人犯》将这个故事讲了出来,引发美国社会极大的反响。

CwPotIoXYAEnStp.jpg

百度十大焦点人物榜单唯一一个商界人物是王健林,是因为他 1 个亿的小目标?

Img466594148.jpg

科技:iPhone 放哪都是焦点,虚拟现实在中国炒得火热

屏幕快照 2016-12-18 16.41.51.png

这两个榜单,一个是消费者科技,一个是科技事件,对比意义不大,因此只做简单阐述。

Google 全球热搜消费者科技榜单中几乎全部是手机:iPhone 占了 4 个位置,Google Pixel, Samsung Galaxy S7, Note 7, Samsung J7(一款中端手机)也榜上有名。任天堂的第八代主机 Switch 是唯一一台非手机设备。

freedom251-1022x1024.jpg

值得一提的是 Freedom 251。这台印度手机仅售 4 美金(人民币 26 元左右),今年 2 月份发布后一直处于舆论漩涡:把其他厂商的手机拿过来改、手机上市一再延期、公司已经倒闭等等。

且不论 4 美金手机的真假,印度市场对廉价手机的需求的确非常大——Freedom 251 开售第一天就收到了 3 万个订单。

百度十大科技事件榜单第一名是虚拟现实走向主流,然而事实证明,大众只是知道了虚拟现实,而没有足够的动力去消费它。

VR-Trend-in-China-Article-Image1.png

排在虚拟现实后面的依次是:引力波、围棋 AI, 载人飞船、无人车、基因测序、机器学习、无人机、比特币、人形机器人,随便一个都是高新技术啊。

至于第七名的百度大脑,公关部门估计起了不少作用,有广告之嫌。而 PowerEgg 无人机上榜可能是因为深陷 1 亿元众筹金额作假风波,它产品本身的含金量有多大,还有待商榷。

电影:全球人民都关注超级英雄电影,《大鱼海棠》在国内话题性十足

屏幕快照 2016-12-18 16.42.19.png

超级英雄电影占了 Google 全球热搜电影榜 5 成,3 部漫威,2 部 DC。可惜的是,排名榜首的《死侍》和《自杀小队》今年都没能引进中国。

deadpooljpg-0d7bb9_1280w.jpg

百度十大热搜电影榜单中,9 部都是电影工业流水线上的商业片,只有《大鱼海棠》制作过程比较艰难。且不论《大鱼海棠》电影本身如何,其话题性和关注度是很多商业片都不及的。

而 Google 和百度两个榜单都有的年度热门电影是《疯狂动物城》和《美国队长 3》。

Google 和百度两个榜单还有很多其他细分类别,这里不一一展示,点击链接自己看吧:


题图来自: 《If Google Was A Guy》

解析:机器人系统架构有哪些特殊技巧?

$
0
0

雷锋网按:本文作者Top Liu,易科机器人实验室系统设计师,机器人技术传播者,译著有《机器人编程实战》、《嵌入式机器人学》等。雷锋网独家发布,转载请联系授权。

机器人编程涉及控制系统的设计与实现,包括环境感知、交互、移动及行为的控制。

一个理想的机器人编程过程包括(假定硬件已经一切就绪):

1.系统架构设计

2.具体功能的算法实现

3.编码与集成

由于笔者所从事工作性质,主要集中在:1.系统设计和2.算法的研究上,3.coding的机会并不是很多。第二个原因是:如果1、2工作完成后,3的工作其实和机器人本身并不大,计算机专业恐怕会做的更好。因此本文主要就1给出一些总结和建议。另外,由于所研究的算法过(wu)于(fa)先(ying)进(yong),通常会在专业的学术期刊上发表,在此也不做过多讨论。

一、机器人系统架构

“架构可定义为组件的结构及它们之间的关系,以及规范其设计和后续进化的原则和指南。简言之,架构是构造与集成软件密集型系统的深层次设计。”

系统架构也可称其为如何实施解决方案的一个策略性设计(例如基于组件的工程标准、安全)和解决方案做什么的功能性设计(如算法、设计模式、底层实现)。

图1 机器人功能分解

另外, 软件工程的基本要求包括模块化、代码可复用、功能可共享。使用通用的框架,有利于分解开发任务及代码移植。机器人软件同样遵从软件工程的一般规律。说白了,架构就是你如何把机器人的功能打散,再如何把代码组织起来。 一个清晰的与项目相匹配的架构直接决定了你的开发效率甚至最终功能的成败。

从人类第一台可编程的机器人开发伊始,架构问题就与之相伴而生。早在1996年,Garlan 和 Shaw在《软件架构:一门新兴学科的展望》就总结了移动机器人的基本设计需求, 如:(1) 慎思规划和反应式行为;(2)容许不确定性;(3)考虑危险;(4)灵活性强。针对这些要求,他们评估了四种用于移动机器人的架构,包括控制回路(control loop)、分层(layers)、隐式调用(implicit invocation)、黑板(blackboard)。经过了几十年的实践,一些架构被逐渐淘汰,一些架构逐渐被完善起来。

注意:现在很多机器人开发者一上手就是ROS,虽然ROS是一种比较不错的系统架构,它的基于node的思想在当时是非常先进的,在今天已成为主流。但我们也要清楚,它只是其中一种架构,尤其是在小型嵌入式设备上定制机器人系统时,其他的架构可能会更有效率。另外Master中央控制模式,也是单机时代的产物,在多机的情形就不是很适用。

| 1.S-P-A结构

图2 机器人的“see-think-act”工作模式

 

图3 “传感——计划——行动”(SPA)结构

机器人天然的工作模式是“see-think-act”,所以自然而然的就形成了 “传感——计划——行动”(SPA)结构:从感知进行映射,经由一个内在的世界模型构造,再由此模型规划一系列的行动,最终在真实的环境中执行这些规划。与之对应的软件结构称为 经典模型,也称为层次模型、功能模型、工程模型或三层模型,这是一种由上至下执行的可预测的软件结构,

SPA机器人系统典型的结构是中建立有三个抽象层,分别称为 行驶层(Pilot)(最低层)、 导航层(Navigator)(中间层)、 规划层(Planner)(最高层)。传感器获取的载体数据由下两层预处理后再到达最高“智能”层作出行驶决策,实际的行驶(如导航和低层的行驶功能)交由下面各层执行,最低层再次成为与小车的接口,将驾驶指令发送给机器人的执行器。

缺点:这种方法强调世界模型的构造并以此模型规划行动,而构造符号模型需要大量的计算时间,这对机器人的性能会有显著的影响。另外,规划模型与真实环境的偏差将导致机器人的动作无法达到预期的效果。

| 2.基于行为的结构

 

图4 基于行为的结构

由于SPA系统过于死板,出现了另一种实现方法: 基于行为的方法。基于行为方法前身是反应式系统,反应式系统并不采用符号表示,却能够生成合理的复合行为。基于行为机器人方案进一步扩展了简单反应式系统的概念,使得简单的并发行为可以结合起来工作。

小历史:Joe Jones和Daniel Roth于2003年出版的《Robot Programming:A Practical Guide to Behavior-Based Robotics》以及使用基于行为系统的iRobot扫地机器人的大获成功(通过基于行为的系统可有效实现遍历、避免在某处卡死等多个目标的达成),标志着当年基于行为系统结构的统治地位。短短十年间,SLAM的迅速兴起,基于地图的规划和导航再次兴起,很多人似乎忘记了或压根就没听说过Behavior-Based Robotics的存在。

图5 《基于行为的机器人编程》

基于行为的软件模型是一种由下至上的设计,因而其结果不易预测,每一个机器人 功能性(functionality)被封装成一个小的独立的模块,称为一个“行为”,而不是编写一整个大段的代码。因为所有的行为并行执行,所以不需要设置优先级。此种设计的目的之一是为了易于扩展,例如便于增加一个新的传感器或向机器人程序里增加一个新的行为特征。所有的行为可以读取载体所有传感器的数据,但当归集众多的行为向执行器产生单一的输出信号时,则会出现问题。

最初的行为之间使用固定的优先级,而在现代的应用中则采用更加灵活的选择方案。

“基于行为机器人学”主要特点包括(参见《嵌入式机器人学》):

1)感应与动作的紧密耦合

在某种程度上,所有行为机器人的动作是对刺激的反应而不是依赖于有意识的规则。回避使用思考规划,取而代之的是一些计算简化的模块来实现从输入到执行的映射,此举有利于快速响应。基于这个观察Brooks言简意概的表达出来其中的原理——“规划不过是一种回避计算下一步要做什么的方法”。

2)避开知识的符号表示

对环境的处理上不需要构造一个内部模型以用于执行规划任务,而是 采用真实世界“它自己最好的模型”。机器人直接从观测中获取到未来的行为,而非试图去生成一个能够内部操作的世界的抽象表示并以此作为规划未来行动的基础。

3)分解成具有因果意义的单元

行为按照状态——动作成对出现,设计为对特定的状态做出确定的动作响应。

4)并发关联行为的时变等级调整

为适应所要达成任务目的,在运行期间采用一个控制方案来改变行为的激活等级。

5)行为选择

在基于行为系统中运行着一定数目作为并行进程的行为,每一个行为可以读取所有的传感器(读动作),但只有一个行为可获得机器人执行器或行驶机构的控制权(写动作)。因此需要一个全局控制器在恰当的时机来协助行为选择(或是行为激活、或是行为输出融合)以达到预期的目的。这将系统的设计工作,就从描述系统本身转移到定义一个正常工作的系统的输出上。

说多了,感觉要跑题了。如果你有兴趣,并想了解更多关于编程机器人来处理未知的东西,推荐Ronald Arkin的《Behavior-Based Robotics》和Thomas Braun的《嵌入式机器人学:基于嵌入式系统的移动机器人设计和应用》。慎思式的机器人编程方法,从中级到高级的探讨,推荐Christopher A. Rouff等人的《Agent Technology from a Formal Perspective》。

一张图小结一下

二、混合系统:实践的产物

没有万灵的结构,混合系统结合了SPA和反应体系的原理,将多种混合系统应用于在传感器和电机输出间进行协调来完成任务。混合结构相结合最具吸引力的好处可能是:系统按照有利于完成任务的标准进行设计,而非刻板的遵循某一教条。但再复杂的机构,基本上也都是二者的组合。以ROS的导航包为例:

图6 ROS导航包

导航包整体上是SPA结构,左右两侧是感知S,包括传感器数据/里程计/地图等,中间框图是Global和Local两级规划P,最后发送cmd_vel给行动A。

如果世界是完美的,那按照规划的地图行进到目的地就完事了。然而基于行为方法就是为了处理各种意外而生的。当机器人遇到障碍物或是被卡住的时候,内嵌的基于行为的系统就开始发挥作用。会根据情况,在“行为库”recovery_behaviors中调用某一预先设定的“行为”来摆脱困境。

图7 recovery_behaviors

默认的行为是:首先,清除机器人地图指定区域以外的障碍。接下来,如果可能的话,机器人将执行一个原地旋转清理空间。如果这也失败了,机器人将更激进地清理地图,清除一切可以原地旋转的矩形区域以外的障碍。这将是另一个就地旋转紧随其后。如果这些都失败了,机器人将认为其目标不可行,停止运行并通知用户。

当然,你还可以针对各种意外设计更为复杂的recovery_behaviors “行为库”以备调用。

三、安全自主机器人应用框架

现在还有一种基于场景和态势的设计框架SARAA,我觉得很有趣。 安全自主机器人应用架构(SARAA,Safe Autonomous Robot Application Architecture, SARAA)是一种强调安全性的自主机器人的开发方法。

图8 SARAA

SARAA机器人总结

在《机器人编程实战》(2017年出版)书中,详细介绍了编程一个机器人自主执行其任务、构成了所谓SARAA的7项技术:

软件机器人框架

ROLL模型

REQUIRE

RSVP

SPACES

STORIES

PASS

我们称具有这种体系结构的机器人为SARAA机器人。当正确地实现时,这些编程技术产生一个基于知识的机器人控制器。因此,一个SARAA机器人是一个可以在预先设定的场景和态势中自主行动的知识型机器人。其中一个设计思想是根据场景和态势对前提/后置条件的判断以提高安全性。

感兴趣可访问 Ctest实验室,SARAA已经用于在开源机器人平台内工作,例如Arduino、Linux和ROS。如果对编程SARAA机器人的场景和态势很好理解与恰当定义,则SARAA机器人的设计有助于提升机器人的安全性。


如何基于日志,同步实现数据的一致性和实时抽取?

$
0
0

作者:王东

宜信技术研发中心架构师

  • 目前就职于宜信技术研发中心,任架构师,负责流式计算和大数据业务产品解决方案。
  • 曾任职于Naver china(韩国最大搜索引擎公司)中国研发中心资深工程师,多年从事CUBRID分布式数据库集群开发和CUBRID数据库引擎开发

    http://www.cubrid.org/blog/news/cubrid-cluster-introduction/

主题简介:

  1. DWS的背景介绍
  2. dbus+wormhole总体架构和技术实现方案
  3. DWS的实际运用案例

前言

大家好,我是王东,来自宜信技术研发中心,这是我来社群的第一次分享,如果有什么不足,请大家多多指正、包涵。

本次分享的主题是《基于日志的DWS平台实现和应用》,主要是分享一下目前我们在宜信做的一些事情。这个主题里面包含到2个团队很多兄弟姐妹的努力的结果(我们团队和山巍团队的成果)。这次就由我代为执笔,尽我努力给大家介绍一下。

其实整个实现从原理上来说是比较简单的,当然也涉及到不少技术。我会尝试用尽量简单的方式来表达,让大家了解这个事情的原理和意义。在过程中,大家有问题可以随时提出,我会尽力去解答。

DWS是一个简称,是由3个子项目组成,我稍后做解释。

一、背景

事情是从公司前段时间的需求说起,大家知道宜信是一个互联网金融企业,我们的很多数据与标准互联网企业不同,大致来说就是:

互联网金融

玩数据的人都知道数据是非常有价值的,然后这些数据是保存在各个系统的数据库中,如何让需要数据的使用方得到一致性、实时的数据呢?

过去的通用做法有几种是:

  1. DBA开放各个系统的备库,在业务低峰期(比如夜间),使用方各自抽取所需数据。由于抽取时间不同,各个数据使用方数据不一致,数据发生冲突,而且重复抽取,相信不少DBA很头疼这个事情。
  2. 公司统一的大数据平台,通过Sqoop 在业务低峰期到各个系统统一抽取数据, 并保存到Hive表中, 然后为其他数据使用方提供数据服务。这种做法解决了一致性问题,但时效性差,基本是T+1的时效。
  3. 基于trigger的方式获取增量变更,主要问题是业务方侵入性大,而且trigger也带来性能损失。

这些方案都不算完美。我们在了解和考虑了不同实现方式后,最后借鉴了 linkedin的思想,认为要想同时解决数据一致性和实时性,比较合理的方法应该是来自于log。

log

(此图来自:https://www.confluent.io/blog/using-logs-to-build-a-solid-data-infrastructure-or-why-dual-writes-are-a-bad-idea/)

把增量的Log作为一切系统的基础。后续的数据使用方,通过订阅kafka来消费log。

比如:

  • 大数据的使用方可以将数据保存到Hive表或者Parquet文件给Hive或Spark查询;
  • 提供搜索服务的使用方可以保存到Elasticsearch或HBase 中;
  • 提供缓存服务的使用方可以将日志缓存到Redis或alluxio中;
  • 数据同步的使用方可以将数据保存到自己的数据库中;
  • 由于kafka的日志是可以重复消费的,并且缓存一段时间,各个使用方可以通过消费kafka的日志来达到既能保持与数据库的一致性,也能保证实时性;

为什么使用log和kafka作为基础,而不使用Sqoop进行抽取呢? 因为:

kafka

为什么不使用dual write(双写)呢?,请参考https://www.confluent.io/blog/using-logs-to-build-a-solid-data-infrastructure-or-why-dual-writes-are-a-bad-idea/

我这里就不多做解释了。

二、总体架构

于是我们提出了构建一个基于log的公司级的平台的想法。

下面解释一下DWS平台, DWS平台是有3个子项目组成:

  1. Dbus(数据总线):负责实时将数据从源端实时抽出,并转换为约定的自带schema的json格式数据(UMS 数据),放入kafka中;
  2. Wormhole(数据交换平台):负责从kafka读出数据 将数据写入到目标中;
  3. Swifts(实时计算平台):负责从kafka中读出数据,实时计算,并将数据写回kafka中。

DWS

图中:

  • Log extractor和dbus共同完成数据抽取和数据转换,抽取包括全量和增量抽取。
  • Wormhole可以将所有日志数据保存到HDFS中; 还可以将数据落地到所有支持jdbc的数据库,落地到HBash,Elasticsearch,Cassandra等;
  • Swifts支持以配置和SQL的方式实现对进行流式计算,包括支持流式join,look up,filter,window aggregation等功能;
  • Dbus web是dbus的配置管理端,rider除了配置管理以外,还包括对Wormhole和Swifts运行时管理,数据质量校验等。

由于时间关系,我今天主要介绍DWS中的Dbus和Wormhole,在需要的时候附带介绍一下Swifts。

三、dbus解决方案

日志解析

如前面所说,Dbus主要解决的是将日志从源端实时的抽出。 这里我们以MySQL为例子,简单说明如何实现。

我们知道,虽然MySQL InnoDB有自己的log,MySQL主备同步是通过binlog来实现的。如下图:

MySQL InnoDB

图片来自:https://github.com/alibaba/canal

而binlog有三种模式:

  1. Row 模式:日志中会记录成每一行数据被修改的形式,然后在slave端再对相同的数据进行修改。
  2. Statement 模式: 每一条会修改数据的sql都会记录到 master的bin-log中。slave在复制的时候SQL进程会解析成和原来master端执行过的相同的SQL来再次执行。
  3. Mixed模式: MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。

他们各自的优缺点如下:

Mixed模式

此处来自:http://www.jquerycn.cn/a_13625

由于statement 模式的缺点,在与我们的DBA沟通过程中了解到,实际生产过程中都使用row 模式进行复制。这使得读取全量日志成为可能。

通常我们的MySQL布局是采用 2个master主库(vip)+ 1个slave从库 + 1个backup容灾库 的解决方案,由于容灾库通常是用于异地容灾,实时性不高也不便于部署。

为了最小化对源端产生影响,显然我们读取binlog日志应该从slave从库读取。

读取binlog的方案比较多,github上不少,参考https://github.com/search?utf8=%E2%9C%93&q=binlog。最终我们选用了阿里的canal做位日志抽取方。

Canal最早被用于阿里中美机房同步, canal原理相对比较简单:

  1. Canal模拟MySQL Slave的交互协议,伪装自己为MySQL Slave,向MySQL Slave发送dump协议
  2. MySQL master收到dump请求,开始推送binary log给Slave(也就是canal)
  3. Canal解析binary log对象(原始为byte流)

MySQL

图片来自:https://github.com/alibaba/canal

解决方案

Dbus 的MySQL版主要解决方案如下:

MySQL

对于增量的log,通过订阅Canal Server的方式,我们得到了MySQL的增量日志:

  • 按照Canal的输出,日志是protobuf格式,开发增量Storm程序,将数据实时转换为我们定义的UMS格式(json格式,稍后我会介绍),并保存到kafka中;
  • 增量Storm程序还负责捕获schema变化,以控制版本号;
  • 增量Storm的配置信息保存在Zookeeper中,以满足高可用需求。
  • Kafka既作为输出结果也作为处理过程中的缓冲器和消息解构区。

在考虑使用Storm作为解决方案的时候,我们主要是认为Storm有以下优点:

  • 技术相对成熟,比较稳定,与kafka搭配也算标准组合;
  • 实时性比较高,能够满足实时性需求;
  • 满足高可用需求;
  • 通过配置Storm并发度,可以活动性能扩展的能力;

全量抽取

对于流水表,有增量部分就够了,但是许多表需要知道最初(已存在)的信息。这时候我们需要initial load(第一次加载)。

对于initial load(第一次加载),同样开发了全量抽取Storm程序通过jdbc连接的方式,从源端数据库的备库进行拉取。initial load是拉全部数据,所以我们推荐在业务低峰期进行。好在只做一次,不需要每天都做。

全量抽取,我们借鉴了Sqoop的思想。将全量抽取Storm分为了2 个部分:

  1. 数据分片
  2. 实际抽取

数据分片需要考虑分片列,按照配置和自动选择列将数据按照范围来分片,并将分片信息保存到kafka中。

kafka

下面是具体的分片策略:

分片需求

全量抽取的Storm程序是读取kafka的分片信息,采用多个并发度并行连接数据库备库进行拉取。因为抽取的时间可能很长。抽取过程中将实时状态写到Zookeeper中,便于心跳程序监控。

Zookeeper

统一消息格式

无论是增量还是全量,最终输出到kafka中的消息都是我们约定的一个统一消息格式,称为UMS(unified message schema)格式。

如下图所示:

UMSinfluxdb

消息中schema部分,定义了namespace 是由 类型+数据源名+schema名+表名+版本号+分库号+分表号 能够描述整个公司的所有表,通过一个namespace就能唯一定位。

  • _ums_op_ 表明数据的类型是I(insert),U(update),D(删除);
  • _ums_ts_ 发生增删改的事件的时间戳,显然新的数据发生的时间戳更新;
  • _ums_id_ 消息的唯一id,保证消息是唯一的,但这里我们保证了消息的先后顺序(稍后解释);

payload是指具体的数据,一个json包里面可以包含1条至多条数据,提高数据的有效载荷。

UMS中支持的数据类型,参考了Hive类型并进行简化,基本上包含了所有数据类型。

全量和增量的一致性

在整个数据传输中,为了尽量的保证日志消息的顺序性,kafka我们使用的是1个partition的方式。在一般情况下,基本上是顺序的和唯一的。

但是我们知道写kafka会失败,有可能重写,Storm也用重做机制,因此,我们并不严格保证exactly once和完全的顺序性,但保证的是at least once。

因此_ums_id_变得尤为重要。

对于全量抽取,_ums_id_是唯一的,从zk中每个并发度分别取不同的id片区,保证了唯一性和性能,填写负数,不会与增量数据冲突,也保证他们是早于增量消息的。

对于增量抽取,我们使用的是MySQL的日志文件号 + 日志偏移量作为唯一id。Id作为64位的long整数,高7位用于日志文件号,低12位作为日志偏移量。

例如:000103000012345678。 103 是日志文件号,12345678 是日志偏移量。

这样,从日志层面保证了物理唯一性(即便重做也这个id号也不变),同时也保证了顺序性(还能定位日志)。通过比较_ums_id_ 消费日志就能通过比较_ums_id_知道哪条消息更新。

其实_ums_ts_与_ums_id_意图是类似的,只不过有时候_ums_ts_可能会重复,即在1毫秒中发生了多个操作,这样就得靠比较_ums_id_了。

心跳监控和预警

整个系统涉及到数据库的主备同步,Canal Server,多个并发度Storm进程等各个环节。

因此对流程的监控和预警就尤为重要。

通过心跳模块,例如每分钟(可配置)对每个被抽取的表插入一条心态数据并保存发送时间,这个心跳表也被抽取,跟随着整个流程下来,与被同步表在实际上走相同的逻辑(因为多个并发的的Storm可能有不同的分支),当收到心跳包的时候,即便没有任何增删改的数据,也能证明整条链路是通的。

Storm程序和心跳程序将数据发送公共的统计topic,再由统计程序保存到influxdb中,使用grafana进行展示,就可以看到如下效果:

grafana

图中是某业务系统的实时监控信息。上面是实时流量情况,下面是实时延时情况。可以看到,实时性还是很不错的,基本上1~2秒数据就已经到末端kafka中。

Granfana提供的是一种实时监控能力。

如果出现延时,则是通过dbus的心跳模块发送邮件报警或短信报警。

实时脱敏

考虑到数据安全性,对于有脱敏需求的场景,Dbus的全量storm和增量storm程序也完成了实时脱敏的功能。脱敏方式有3种:

storm

总结一下:简单的说,Dbus就是将各种源的数据,实时的导出,并以UMS的方式提供订阅, 支持实时脱敏,实际监控和报警。

四、Wormhole解决方案

说完Dbus,该说一下Wormhole,为什么两个项目不是一个,而要通过kafka来对接呢?

其中很大一个原因就是解耦,kafka具有天然的解耦能力,程序直接可以通过kafka做异步的消息传递。Dbus和Wornhole内部也使用了kafka做消息传递和解耦。

另外一个原因就是,UMS是自描述的,通过订阅kafka,任何有能力的使用方来直接消费UMS来使用。

虽然UMS的结果可以直接订阅,但还需要开发的工作。Wormhole解决的是:提供一键式的配置,将kafka中的数据落地到各种系统中,让没有开发能力的数据使用方通过wormhole来实现使用数据。

wormhole

如图所示,Wormhole 可以将kafka中的UMS 落地到各种系统,目前用的最多的HDFS,JDBC的数据库和HBase。

在技术栈上, wormhole选择使用spark streaming来进行。

在Wormhole中,一条flow是指从一个namaspace从源端到目标端。一个spark streaming服务于多条flow。

flow

选用Spark的理由是很充分的:

  • Spark天然的支持各种异构存储系统;
  • 虽然Spark Stream比Storm延时稍差,但Spark有着更好的吞吐量和更好的计算性能;
  • Spark在支持并行计算方面有更强的灵活性;
  • Spark提供了一个技术栈内解决Sparking Job,Spark Streaming,Spark SQL的统一功能,便于后期开发;

这里补充说一下Swifts的作用:

  • Swifts的本质是读取kafka中的UMS数据,进行实时计算,将结果写入到kafka的另外一个topic。
  • 实时计算可以是很多种方式:比如过滤filter,projection(投影),lookup, 流式join window aggregation,可以完成各种具有业务价值的流式实时计算。

Wormhole和Swifts对比如下:

Wormhole

落HDFS

通过Wormhole Wpark Streaming程序消费kafka的UMS,首先UMS log可以被保存到HDFS上。

kafka一般只保存若干天的信息,不会保存全部信息,而HDFS中可以保存所有的历史增删改的信息。这就使得很多事情变为可能:

  • 通过重放HDFS中的日志,我们能够还原任意时间的历史快照。
  • 可以做拉链表,还原每一条记录的历史信息,便于分析;
  • 当程序出现错误是,可以通过回灌(backfill),重新消费消息,重新形成新的快照。

可以说HDFS中的日志是很多的事情基础。

介于Spark原生对parquet支持的很好,Spark SQL能够对Parquet提供很好的查询。UMS落地到HDFS上是保存到Parquet文件中的。Parquet的内容是所有log的增删改信息以及_ums_id_,_ums_ts_都存下来。

Wormhole spark streaming根据namespace 将数据分布存储到不同的目录中,即不同的表和版本放在不同目录中。

namespace

由于每次写的Parquet都是小文件,大家知道HDFS对于小文件性能并不好,因此另外还有一个job,每天定时将这些的Parquet文件进行合并成大文件。

每个Parquet文件目录都带有文件数据的起始时间和结束时间。这样在回灌数据时,可以根据选取的时间范围来决定需要读取哪些Parquet文件,不必读取全部数据。

插入或更新数据的幂等性

常常我们遇到的需求是,将数据经过加工落地到数据库或HBase中。那么这里涉及到的一个问题就是,什么样的数据可以被更新到数据?

这里最重要的一个原则就是数据的幂等性。

无论是遇到增删改任何的数据,我们面临的问题都是:

  1. 该更新哪一行;
  2. 更新的策略是什么。

对于第一个问题,其实就需要定位数据要找一个唯一的键,常见的有:

  1. 使用业务库的主键;
  2. 由业务方指定几个列做联合唯一索引;

对于第二个问题,就涉及到_ums_id_了,因为我们已经保证了_ums_id_大的值更新,因此在找到对应数据行后,根据这个原则来进行替换更新。

_ums_id_

之所以要软删除和加入_is_active_列,是为了这样一种情况:

如果已经插入的_ums_id_比较大,是删除的数据(表明这个数据已经删除了), 如果不是软删除,此时插入一个_ums_id_小的数据(旧数据),就会真的插入进去。

这就导致旧数据被插入了。不幂等了。所以被删除的数据依然保留(软删除)是有价值的,它能被用于保证数据的幂等性。

HBase的保存

插入数据到Hbase中,相当要简单一些。不同的是HBase可以保留多个版本的数据(当然也可以只保留一个版本)默认是保留3个版本;

因此插入数据到HBase,需要解决的问题是:

  1. 选择合适的rowkey:Rowkey的设计是可以选的,用户可以选择源表的主键,也可以选择若干列做联合主键。
  2. 选择合适的version:使用_ums_id_+ 较大的偏移量(比如100亿) 作为row的version。

Version的选择很有意思,利用_ums_id_的唯一性和自增性,与version自身的比较关系一致:即version较大等价于_ums_id_较大,对应的版本较新。

从提高性能的角度,我们可以将整个Spark Streaming的Dataset集合直接插入到HBase,不需要比较。让HBase基于version自动替我们判断哪些数据可以保留,哪些数据不需要保留。

Jdbc的插入数据:

插入数据到数据库中,保证幂等的原理虽然简单,要想提高性能在实现上就变得复杂很多,总不能一条一条的比较然后在插入或更新。

我们知道Spark的RDD/dataset都是以集合的方式来操作以提高性能,同样的我们需要以集合操作的方式实现幂等性。

具体思路是:

  1. 首先根据集合中的主键到目标数据库中查询,得到一个已有数据集合;
  2. 与dataset中的集合比较,分出两类:

A:不存在的数据,即这部分数据insert就可以;

B:存在的数据,比较_ums_id_, 最终只将哪些_ums_id_更新较大row到目标数据库,小的直接抛弃。

使用Spark的同学都知道,RDD/dataset都是可以partition的,可以使用多个worker并进行操作以提高效率。

在考虑并发情况下,插入和更新都可能出现失败,那么还有考虑失败后的策略。

比如:因为别的worker已经插入,那么因为唯一性约束插入失败,那么需要改为更新,还要比较_ums_id_看是否能够更新。

对于无法插入其他情况(比如目标系统有问题),Wormhole还有重试机制。说起来细节特别多。这里就不多介绍了。

有些还在开发中。

插入到其他存储中的就不多介绍了,总的原则是:根据各自存储自身特性,设计基于集合的,并发的插入数据实现。这些都是Wormhole为了性能而做的努力,使用Wormhole的用户不必关心 。

五、运用案例

实时营销

说了那么多,DWS有什么实际运用呢?下面我来介绍某系统使用DWS实现了的实时营销。

DWS

如上图所示:

系统A的数据都保存到自己的数据库中,我们知道,宜信提供很多金融服务,其中包括借款,而借款过程中很重要的就是信用审核。

借款人需要提供证明具有信用价值的信息,比如央行征信报告,是具有最强信用数据的数据。 而银行流水,网购流水也是具有较强的信用属性的数据。

借款人通过Web或手机APP在系统A中填写信用信息时,可能会某些原因无法继续,虽然可能这个借款人是一个优质潜在客户,但以前由于无法或很久才能知道这个信息,所以实际上这样的客户是流失了。

应用了DWS以后,借款人已经填写的信息已经记录到数据库中,并通过DWS实时的进行抽取、计算和落地到目标库中。根据对客户的打分,评价出优质客户。然后立刻将这个客户的信息输出到客服系统中。

客服人员在很短的时间(几分钟以内)就通过打电话的方式联系上这个借款人(潜客),进行客户关怀,将这个潜客转换为真正的客户。我们知道借款是有时效性的,如果时间太久就没有价值了。

如果没有实时抽取/计算/落库的能力,那么这一切都无法实现。

实时报表系统

另外一个实时报表的应用如下:

实时报表

我们数据使用方的数据来自多个系统,以前是通过T+1的方式获得报表信息,然后指导第二天的运营,这样时效性很差。

通过DWS,将数据从多个系统中实时抽取,计算和落地,并提供报表展示,使得运营可以及时作出部署和调整,快速应对。

六、总结

说了那么多,大致总结一下:

  • DWS技术上基于主流实时流式大数据技术框架,高可用大吞吐强水平扩容,低延迟高容错最终一致。
  • DWS能力上支持异构多源多目标系统,支持多数据格式(结构化半结构化非结构化数据)和实时技术能力。
  • DWS将三个子项目合并作为一个平台推出,使得我们具备了实时的能力, 驱动各种实时场景应用。

适合场景包括:实时同步/实时计算/实时监控/实时报表/实时分析/实时洞察/实时管理/实时运营/实时决策

感谢大家的聆听,此次分享到此为止。

Q&A

Q1:Oracle log reader有开源方案吗?

A1:对于Oracle业界也有许多商业解决方案,例如:Oracle GoldenGate(原来的goldengate), Oracle Xstream, IBM InfoSphere Change Data Capture(原来的DataMirror),Dell SharePlex (原来的Quest),国内的DSG superSync等,开源的方案好用的很少。

Q2:这个项目投入了多少人力物力?感觉有点复杂。

Q2:DWS是三个子项目组成,平均每个项目5~7人。是有点复杂,其实也是试图使用大数据技术来解决我们公司目前遇到的困难。

因为是搞大数据相关技术,所有团队里面的兄弟姐妹都还是比较happy的:)

其实这里面,Dbus和Wormhole相对固定模式化,容易轻松复用。Swifts实时计算是与每个业务相关比较大的,自定义比较强,相对比较麻烦一些。

Q3:宜信的这个DWS系统会开源么?

A3:我们也考虑过向社区贡献,就像宜信的其他开源项目一样,目前项目刚刚成形,还有待进一步磨炼,我相信未来的某个时候,我们会给它开源出来。

Q4:架构师怎么理解,是不是系统工程师?

A4:不是系统工程师,在我们宜信有多位架构师,应该算是以技术驱动业务的技术管理人员。包含产品设计,技术管理等。

Q5:复制方案是否是OGG?

A5:OGG与上面提到的其他商业解决方案都是可选方案。

文章出处:DBAplus社群(dbaplus)

2016 年谷歌开源了这些超酷炫的项目

$
0
0

摘要: 人工智能可以可以创作艺术和谱写曲子了,手机传感器也可以成为强大的研究实验室了,普通耳机也可以实现 VR 中的 3D 全景音效了……这些你还不知道?来看看谷歌的这些超酷的开源项目吧!

开放源代码软件让 Google 能够无需重新发明轮子就能够快速有效地进行开发,也让我们能够集中注意力来解决新问题。我们知道,支持开源,就是站在了巨人的肩膀上,所以 Google 员工能够轻松地将他们在内部工作的项目作为开放源代码发布。

我们已经发布了超过 2000 万行的开源代码,包括 Android,Angular,Chromium,Kubernetes 和 TensorFlow 等项目。 我们的版本还包括许多您可能不熟悉的项目,例如 Cartographer,Omnitone 和 Yeoman。

回顾我们在 2016 年开源的项目,有很多令人兴奋的事情。 我们发布了很多开源软件、硬件和数据集,来看看今年的一些版本。

负载均衡系统 Seesaw

Seesaw 是由我们网络可靠性工程师用 Go 语言开发的基于 Linux 虚拟服务器的负载平衡平台,就像所有好的项目一样,这个项目也是为了解决实际问题而产生的。

Seesaw 发布的博客中这样写道:“我们需要能够处理单播(unicast)和任播(anycast)虚拟 IP (VIPs) 流量,使用 NAT 和 DSR (也被称为 DR) 执行负载均衡,执行针对后端的健康检查。特别是,我们需要一个容易管理的平台,可以自动部署配置的变化。在评估了一些包括现有的开源项目的平台之后,我们没能找出一个能够满足我们所有需求的平台,所以我们决定自己着手开发一个可靠和可伸缩的负载均衡平台。”

它让我们提高了服务可用性并降低了管理开销。我们很高兴能够把它分享出来,希望其他企业也能够从中受益。

供应商安全评估调查问卷 VSAQ

VSAQ (Vendor Security Assessment Questionnaire,供应商安全评估调查问卷)是一种能够自适应式评估多种供应商安全和隐私防护策略的评估调查问卷。

我们每年对数百家供应商的安全性进行评估,因此开发了 VSAQ 来自动化大部分初始信息的收集。许多供应商发现我们的问卷直观灵活,所以我们决定分享出来。 VSAQ 框架包括四个可扩展的问卷模板,涵盖 Web 应用程序,隐私程序,基础设施以及物理和数据中心安全。

http://static.cnbetacdn.com/article/2016/0309/baa75ec0cfcb2de.png

Nest 开源的 Thread 协议 OpenThread

Nest 开源的 OpenThread 是基于其 Thread 协议实现的,通过 6LoWPAN 标准连接的智能家居网络。OpenThread 的开发由 ARM,微软,高通,德州仪器和其他主要供应商支持。

OpenThread 是 Nest 主要负责的,而不是 Thread Group。通过 OpenThread,Nest 希望将 Nest 产品中所用的技术在更多供应商和制造商中广泛采用,以加速智能产品家居网络产品的开发进展。随着越来越多的供应商运用 Thread,制造商可以有机会选择一个成熟的网络技术,而不需要创建它们自己的产品,消费者将会有越来越多安全可靠的相关产品可以选择。

创作艺术和谱写曲子的机器智能 Magenta

我们可以使用机器学习创造引人注目的艺术和音乐吗?Magenta 可以帮你实现,它是 Google Brain 团队建立的一个基于 TensorFlow 的项目,目的是提高音乐和艺术生成的机器智能的艺术水平,并建立一个艺术家,程序员和机器学习研究者的协作社区。 

点这里听听谷歌人工智能的第一首歌曲

普通耳机实现 VR 中的 3D 全景音效 Omnitone

虚拟现实(VR)如果没有空间音频的话其实并没有那种身临其境的感觉,而很多 VR 开发都是在专有平台上进行的。Omnitone 是由 Chrome 小组成员建立的一个跨浏览器支持的开源空间音频渲染器,Omnitone 基于标准的 Web Audio API,提供身临其境的体验,可以与 WebVR 等项目一起使用。

原理图:

Google 发布 Omnitone ,为 VR 音频制作带来了什么改变?

实验记录应用 Science Journal

今天的智能手机有很多传感器,可以告诉我们周围的很多有趣的事情。通过这款应用,你可以利用你手机中的各种传感器来测量您的环境,如光和声音,因此您可以绘制您的数据,记录您的实验,并组织您的问题和想法。让手机成为一个强大的研究实验室。

我们推出了 Science Journal 是为了帮助教育工作者、学生和公民科学家利用这些传感器。 

这个你可能觉得没什么用的 App,却意义深远:Google Science Journal

ROS 系统支持的 SLAM 库 Cartographer

Cartographer 是一个利用 ROS 系统支持的 2D 和 3D SLAM(simultaneous localization and mapping)库。 这个库库组合来自各种传感器的数据来计算定位和地图环境。

SLAM 是众多自动驾驶平台的重要组件,比如自动驾驶汽车、仓库中的自动叉车、扫地机器人、UAVs 等。在产业界和学术界常见的传感器配置上,Cartographer 能实时建立全局一致的地图。

文章部分内容编译自: https://opensource.com

原文作者:Google 开源推广团队成员 Josh Simmons

本文链接

Android Things 物联网应用开发初体验

$
0
0

本文在 DiyCode创客日记同时首发,关注作者的 DiyCode帐号或者 微信公众号「造物邦」可第一时间收到新文章推送。

现在大家都变得好奇怪,有了“技术红利期”的概念,一旦有哪个大佬推出什么新技术,第一时间跟上,越往后就越没有你什么事了。“小程序”一开始之所以能那么火,我想应该跟很多人不想错过可能的“红利期”是有关系的,像我这个小白不也跨界凑热闹注册了个小程序的号

在未来还没有流行起来之前,作为开发者的你是不是应该有所准备?

回到主题,最近,Google 发布了 Android Things 开发者预览版,作为一名“资深”的吃瓜群众,趁还有点温度,赶紧凑下热闹。但是,我是有原则的:坚决不刷新闻。要写就来点开发实战,哪怕是“从入门到放弃”,也算是体验了一把开发的乐趣。

Android Things

关于 Android Things

Android Things 是 Google 最近推出的全新物联网操作系统,前身是去年发布的物联网平台 Brillo,除了继承 Brillo 的功能,还加入了 Android Studio、Android SDK、Google Play 服务以及 Google 云平台等 Android 开发者熟悉的工具和服务。任何 Android 开发者现在都可以利用 Android API 和 Google 服务轻松构建智能联网设备了,这就是 Google 说的:

If you can build an app, you can build a device.

Android Things 架构

目前,Android Things 已经能够支持 Intel Edison、NXP Pico、Raspberry Pi 3 等硬件平台,好像高通的 Snapdragon 也已经在赶来的路上了。

Android Things 支持的硬件

还有,Android Things 天生支持物联网通讯协议 Weave,可让所有类型的设备能够连上云端并与其他服务如 Google Assistant 交互,现在已经有一些 IoT 设备像 Nest、Hue、SmartThings、WeMo、LiFX 等前来支援 Weave。这些现在看来都不是什么新的概念,就因为觉得不是什么新的概念,估计这种概念也就已经深入人心、习以为常了。

Weave 图解

混迹开源硬件圈,刚好玩过 Intel Edison 和 Raspberry Pi 3,有点套路了,现在就拿他们来体验一下 Android Things。

Android Things @ Intel Edison

使用 Intel Platform Flash Tool Lite烧录 开发者预览版镜像

烧录开发者预览版镜像

配置你的 Android 开发环境,老司机应该都轻车熟路了。需要下载安装并更新最新版 Android Studio,在天朝这个局域网快速完成此事着实不易:

安装 Android Studio

更新下载 Android Studio 组件

将 Edison 连接到 PC,通过 adb验证设备是否可用,在 macOS 下, adb工具存放在 ~/Library/Android/sdk/platform-tools/

$ cd ~/Library/Android/sdk/platform-tools/
$ ./adb devices

检查设备是否连接
前往 Google 官方 仓库克隆示例,里面有高手必经之路——“ 点灯大法

$ git clone git@github.com:androidthings/sample-simplepio.git

导入 simplepio 示例

BuildRun,一步到位,如果一切顺利的话,Android Monitor 窗口将有 log 输出,板子上的 LED 闪烁:

输出 log

LED 灭

LED 亮

Android Things @ Raspberry Pi 3

安装最新镜像,准备一张 8G 以上容量的 Micro SD 卡,下载 最新镜像,解压,根据开发机器的操作系统,选择相应方式进行烧录:

插上 Micro SD 上电启动系统,可以外接 HDMI 显示器观赏其启动过程:

启动内核中...

启动界面

配置 Wi-Fi,Raspberry Pi 3 不像 Intel Edison 可直接通过 USB 连接至开发机器,需要通过以太网接口进行 IP 连接,之后可以配置 Wi-Fi 无线连接,这样就不需要多余的网线了。

# 先通过有线连接,获取IP
$ ./adb connect <ip-address>
connected to <ip-address>:5555

# adb连接上之后配置 Wi-Fi
$ ./adb shell am startservice \
    -n com.google.wifisetup/.WifiSetupService \
    -a WifiSetupService.Connect \
    -e ssid <Network_SSID> \
    -e passphrase <Network_Passcode>

# 验证是否 Wi-Fi 是否连接成功
$ ./adb logcat -d | grep Wifi
...
V WifiWatcher: Network state changed to CONNECTED
V WifiWatcher: SSID changed: ...
I WifiConfigurator: Successfully connected to ...

# 重启,撤掉网线,获取 Wi-Fi 连接后的设备 IP,可通过 HDMI 显示器获得或从路由器后台获得
$ ./adb connect <wifi-ip-address>
connected to <wifi-ip-address>:5555

# 查看设备是否attached
$ ./adb devices
List of devices attached
<wifi-ip-address>:5555  device

Demo,这次不搞“点灯大法”了,Raspberry Pi 3 既然能够外接显示器,就来玩玩 UI,前往官方仓库克隆代码:

git clone https://github.com/androidthings/sample-simpleui.git

假设你已经安装好 Android Studio,直接打开 sample-simpleui工程, Run一下即可将代码部署到板子上。

运行sample-simpleui

simpleui demo

更多玩法

可以多多关注一下 Android Things 的官方网站或仓库,未来应该会有更多好玩的东西出来:

哈佛大学 NLP 组开源神经机器翻译系统 OpenNMT

$
0
0

今天,Harvard NLP (哈佛大学自然语言处理研究组) 宣布开源其研发的神经机器翻译系统 OpenNMT,该系统使用了 Torch 数学工具包,已达 industrial-strength 可生产水平。

OpenNMT 系统设计简单易用,易于扩展,同时保持效率和最先进的翻译精确度。

特性:

  1. 简单的通用接口,只需要源/目标文件。

  2. 快速高性能GPU训练和内存优化。

  3. 提高翻译性能的最新的研究成果。

  4. 可配对多种语言的预训练模型(即将推出)。

  5. 允许其他序列生成任务的拓展,如汇总和图文生成。

更多信息:

Demo | 文档

高级产品经理做一个需求,和你有什么不同?

$
0
0

人人都是产品经理是中国最大最活跃的产品经理学习、交流、分享社区。集媒体、社区、招聘 、教育、社群活动为一体,全方位服务产品经理。本文由人人都是产品经理社区 专栏作家@莔莔有神 原创发布。转载请联系人人都是产品经理。 

前段时间“高级产品经理与普通产品经理的差异”这个话题讨论得火热,联系到这段时间的工作感悟,从如何做一个需求这个工作中最常见的点,切入讨论,以供反思和讨论。

1 前提

首先定义一下这篇文里提到的两种产品经理。

普通产品经理大约分为两种,一种是资历比较浅、没有亲身经历过足够的版本迭代或产品生命周期的新手;另一种则是可能从业时间较长、也经历过足够的需求历练,但一直在进行重复性的需求处理,没有从更高层或者更深刻的角度去反思自己的业务,从而导致自己的业务能力到达一定水平后就停止爬坡。这里需要说明的是,普通产品经理并不是工作不到位,而是工作侧重执行层面、对工作的思考程度尚浅、还有很大的提升空间。

而文中说的高级产品经理,不与任何公司的等级或头衔挂钩,而是指在完善处理需求的基本业务能力以外,能够拥有自身的产品观与严谨的方法论,并应用在日常每一个需求的处理或决策上。一些高级产品经理仍然奋斗在一线,而另一些已经在管理岗位,虽然不完全直接做需求,但同样会用他的产品观与方法论影响整个团队。

2 做一个需求

那么高级产品经理做一个需求,究竟有什么不同?很早之前我做“零基础进击产品经理”的科普课程时,总结过一个产品经理日常处理需求的流程:需求分析——产品文档——需求评审——跟进开发——需求上线——评估效果——迭代优化。其实无论是高级产品经理,还是普通产品经理,整个流程的差异不大,区别在于期间每个流程的方法论与侧重点。

a. 需求分析

对一个普通产品经理来说,分析需求的步骤很多时候在回答”用户要什么”以及”老板要什么”,能够回答好这两个问题就非常不容易了。而对于高级产品经理来说,在此基础之上,还需要回答两个问题:“业务要什么”以及“产品本身要什么”。

问“业务要什么”,很显然是要考虑公司目标和利益。时代不同,整个行业正在从务虚专享务实,很多公司已经越来越重视盈利性,单纯只考虑用户诉求是不足够的。即便考虑的不是盈利性,也要考虑你当前的需求是否与公司整体目标一致,比如当前公司主推的业务是什么?发力点在哪部分用户?未来一段时间要的是拉新还是留存?我曾经专门在微信群里分享如何基于行业和业务进行产品分析,并整理了文字版发在微信号破壳里,就是给大家一个方法论去回答好业务的问题,进而把握好整个需求的方向。

问“产品本身要什么”,则是对产品本身成长和发展的整体把握。很多产品经理在评估一个需求的时候,觉得是用户需要的、也是业务需要的,就没什么问题了,然而这时候高级产品经理则会再进一步去思考:这个需求后续该如何去迭代?是否与产品本身的规划一致?高级产品经理要做的不光是抓住一个需求点、打造一个功能,更需要考虑清楚这个功能以后如何成长、如何和产品整体规划融合起来。

b 产品文档

文档的表现形式和书写习惯多种多样,这个和公司规模和团队合作都有关系,倒也不能作为区分高级产品经理和普通产品经理的点。这个环节里能让人觉得“高下立现”的有三个点:需求释义;特殊场景;数据追踪。

需求释义是指,高级产品经理要确保自己对需求的理解足够清晰和准确,并够传达给整个团队。普通产品经理需求执行阶段,往往直接就开始写文档描述功能,这就无法把这个功能的重要性传递给整个团队;相反,高级产品经理则会把为什么做这个功能、为什么要这么做、对业务有多大影响这些问题都和团队解释清楚,无论是通过文档本身,还是口头或邮件表述(上面说了各个公司习惯可能不一样),都会是对整体团队的激励,提升技术、测试、运营等团队的参与感,甚至可能在沟通中带来更好的想法,优化实现目标的方案。

特殊场景是说那些主流程以外的流程分支。比如用户登录时输错密码了怎么办?用户输对了密码但是验证码又错了怎么办?突然变成弱网环境怎么办?……普通产品经理能够对主流程梳理地清楚到位,对特殊场景的覆盖往往力不从心;这时候高级产品经理则会尽可能覆盖全这些特殊场景或者是错误分支,给开发团队更明确的处理方案,这么做一方面是确保自身对功能表现的控制力,一方面也是从产品层面确保产品在不同端的体验一致。

到了数据追踪的环节,很多普通产品经理会直接把该打的tracking全部加上,确保没有遗漏即可。有些时候这么做的确也可行,然而如果遇到排期紧张或页面交互复杂的情况,这种做法则会造成开发资源浪费。实际上,做数据追踪的科学方式,是要依据该需求的核心目标而制定,数据追踪所实现的其实是定性目标的量化分解。

举个例子,假设一个电商产品想要增加销量,在首页新增了一个专题功能,目的是引导用户、刺激购买,那么最核心需要追踪的就是点击率和购买率,以及专题触发的点击率和购买率与其他路径带来的有什么不同,是否真的能更加刺激用户购买。比照交互路径,收集的数据应当是设备开启次数、专题区域展示次数、交互路径上可点击区域的展示次数和点击次数,从这个路径触发的商品页展示次数、购买次数等等(其中的次数要考虑到展示设备数、展示人数、实际展示次数的不同)。以目标量化分解为出发点,追踪核心路径的路径并保证数据纯粹性,比盲目打点更能帮你评估功能的效用。

c. 需求评审&跟进开发 

把需求评审和跟进开发写一起,是因为对于高级产品经理来说,由于前期对于需求的处理思考维度更多,方案设计更具说服力,也能够激励到整个团队的协作,在需求评审和跟进开发的环节,反而耗费的精力要小很多。相对地,普通产品经理还沉浸在“如何与程序猿相处”的问题中,甚至在开发环节发现一些问题再做修补,其实都是对精力的损耗。

d. 需求上线 

这个流程其实大家都在做三件事:一是确保功能相关的素材和相关的部门准备完毕;二是功能回测无问题,达到可上线状态;三是上线节奏控制,是否需要内测、分渠道等等。这些其实都没有太大的差异,只是高级产品经理会在细节处理上更到位。比如说,一个新功能的上线,普通产品经理会通知到运营团队准备相关素材或者活动推广,也会主动参与到方案讨论,然而高级产品经理会同时通知到客服团队,做好用户咨询的准备。

虽然是细节,体现的则是考虑更周全。

e. 评估效果

需求上线后到了评估效果的环节,这里就是我之前写的“数据追踪”派上用场了。比起普通产品经理面对数据的再加工,高级产品经理在进行数据追踪时就已经想好了该如何评估这个功能的效果,主要是看哪些指标。

f. 迭代优化

普通产品经理通常是在评估效果后,根据数据反馈对功能做下一轮的调整和优化。然而这会产生一些很棘手的问题:比如说,有些优化会造成版本不兼容(尤其是移动端),这就不得不维护两套逻辑,还要分别考虑到不同版本的用户体验;又比如说,到了下一个版本,这个功能的优化需求被降低优先级了,那么上一个版本的问题可能会在线上待更长时间,回头再处理时就是更恶心的版本不兼容;还有一种可能,时间长了,事情又多,这个优化需求就被大家遗忘了……

高级产品经理在做需求时,首先一个出发点是:不留已知的坑在下个版本优化——因为下个版本可能就优化不了。所以在刚开始做需求设计时,就尽量避免一些有可能会挖坑的设计,或者在上线效果不确定时先做小流量测试,甚至是通过H5页面或者微信生态测试;其次,在需要优化升级时,也会再次根据当时的产品状态和业务要求进行评估,这又回到了第1步的需求分析,完成需求处理的闭环。

3 总结

总结下来,我们会发现与普通产品经理不同,高级产品经理在做需求时有这么几个特质:

  • 重视业务,契合公司战略,回归商业本质;

  • 对需求要有规划,一个好棋手是下棋一步,心中已有九步;

  • 目标清晰,并贯穿需求始终;

  • 激励团队,激发群体智慧,一群人战斗总要好过一个人战斗;

  • 细节决定高下。 

当然,什么“尊重用户”“数据驱动”“团队协作”这些基础素质就不写了(如果还不具备,大多数情况说明还不是一个合格的产品经理),总结的这5点更侧重于一个普通产品经理的自我提升。这5点特质,看上去似乎没有什么,但在实际工作中却是一个产品经理思维高度与业务素养的重要反馈,要想面面俱到的确需要更多付出。

正好也到年末,新年计划的时候,不妨让自己更靠近一个高级产品经理吧。

作者:莔莔有神,公众号破壳(Pokeclub),人人都是产品经理专栏作家,帝都产品狗,负责过亿级用户产品,也有从零到一实现百万日活的经验。爱好是女性视角看产品,产品思维看世界,从独特视角找产品亮点和生活乐趣。

Viewing all 11853 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>