标签 Twitter 下的文章

Twitter 允许用户将博客帖子和文章分享给全世界。使用 Python 和 Tweepy 库使得创建一个 Twitter 机器人来接管你的所有的推特变得非常简单。这篇文章告诉你如何去构建这样一个机器人。希望你能将这些概念也同样应用到其他的在线服务的项目中去。

开始

tweepy 库可以让创建一个 Twitter 机器人的过程更加容易上手。它包含了 Twitter 的 API 调用和一个很简单的接口。

下面这些命令使用 pipenv 在一个虚拟环境中安装 tweepy。如果你没有安装 pipenv,可以看一看我们之前的文章如何在 Fedora 上安装 Pipenv

$ mkdir twitterbot
$ cd twitterbot
$ pipenv --three
$ pipenv install tweepy
$ pipenv shell

Tweepy —— 开始

要使用 Twitter API ,机器人需要通过 Twitter 的授权。为了解决这个问题, tweepy 使用了 OAuth 授权标准。你可以通过在 https://apps.twitter.com/ 创建一个新的应用来获取到凭证。

创建一个新的 Twitter 应用

当你填完了表格并点击了“ 创建你自己的 Twitter 应用 Create your Twitter application ”的按钮后,你可以获取到该应用的凭证。 Tweepy 需要 用户密钥 API Key 用户密码 API Secret ,这些都可以在 “ 密钥和访问令牌 Keys and Access Tokens ” 中找到。

向下滚动页面,使用“ 创建我的访问令牌 Create my access token ”按钮生成一个“ 访问令牌 Access Token ” 和一个“ 访问令牌密钥 Access Token Secret ”。

使用 Tweppy —— 输出你的时间线

现在你已经有了所需的凭证了,打开一个文件,并写下如下的 Python 代码。

import tweepy
auth = tweepy.OAuthHandler("your_consumer_key", "your_consumer_key_secret")
auth.set_access_token("your_access_token", "your_access_token_secret")
api = tweepy.API(auth)
public_tweets = api.home_timeline()
for tweet in public_tweets:
    print(tweet.text)

在确保你正在使用你的 Pipenv 虚拟环境后,执行你的程序。

$ python tweet.py

上述程序调用了 home_timeline 方法来获取到你时间线中的 20 条最近的推特。现在这个机器人能够使用 tweepy 来获取到 Twitter 的数据,接下来尝试修改代码来发送 tweet。

使用 Tweepy —— 发送一条推特

要发送一条推特 ,有一个容易上手的 API 方法 update_status 。它的用法很简单:

api.update_status("The awesome text you would like to tweet")

Tweepy 拓展为制作 Twitter 机器人准备了非常多不同有用的方法。要获取 API 的详细信息,请查看文档

一个杂志机器人

接下来我们来创建一个搜索 Fedora Magazine 的推特并转推这些的机器人。

为了避免多次转推相同的内容,这个机器人存放了最近一条转推的推特的 ID 。 两个助手函数 store_last_idget_last_id 将会帮助存储和保存这个 ID。

然后,机器人使用 tweepy 搜索 API 来查找 Fedora Magazine 的最近的推特并存储这个 ID。

import tweepy

def store_last_id(tweet_id):
    """ Stores a tweet id in text file """
    with open('lastid', 'w') as fp:
        fp.write(str(tweet_id))


def get_last_id():
    """ Retrieve the list of tweets that were
    already retweeted """

    with open('lastid') as fp:
        return fp.read()

if __name__ == '__main__':

    auth = tweepy.OAuthHandler("your_consumer_key", "your_consumer_key_secret")
    auth.set_access_token("your_access_token", "your_access_token_secret")

    api = tweepy.API(auth)

    try:
        last_id = get_last_id()
    except FileNotFoundError:
        print("No retweet yet")
        last_id = None

    for tweet in tweepy.Cursor(api.search, q="fedoramagazine.org", since_id=last_id).items():
        if tweet.user.name  == 'Fedora Project':
            store_last_id(tweet.id)
            #tweet.retweet()
            print(f'"{tweet.text}" was retweeted')

为了只转推 Fedora Magazine 的推特 ,机器人搜索内容包含 fedoramagazine.org 和由 「Fedora Project」 Twitter 账户发布的推特。

结论

在这篇文章中你看到了如何使用 tweepy 的 Python 库来创建一个自动阅读、发送和搜索推特的 Twitter 应用。现在,你能使用你自己的创造力来创造一个你自己的 Twitter 机器人。

这篇文章的演示源码可以在 Github 找到。


via: https://fedoramagazine.org/learn-build-twitter-bot-python/

作者:Clément Verna 选题:lujun9972 译者:Bestony 校对:校对者ID

本文由 LCTT 原创编译,Linux中国 荣誉推出

介绍

KSQL 是 Apache Kafka 中的开源的流式 SQL 引擎。它可以让你在 Kafka 主题 topic 上,使用一个简单的并且是交互式的 SQL 接口,很容易地做一些复杂的流处理。在这个短文中,我们将看到如何轻松地配置并运行在一个沙箱中去探索它,并使用大家都喜欢的演示数据库源: Twitter。我们将从推文的原始流中获取,通过使用 KSQL 中的条件去过滤它,来构建一个聚合,如统计每个用户每小时的推文数量。

Confluent

首先, 获取一个 Confluent 平台的副本。我使用的是 RPM 包,但是,如果你需要的话,你也可以使用 tar、 zip 等等 。启动 Confluent 系统:

$ confluent start

(如果你感兴趣,这里有一个 Confluent 命令行的快速教程

我们将使用 Kafka Connect 从 Twitter 上拉取数据。 这个 Twitter 连接器可以在 GitHub 上找到。要安装它,像下面这样操作:

# Clone the git repo
cd /home/rmoff
git clone https://github.com/jcustenborder/kafka-connect-twitter.git
# Compile the code
cd kafka-connect-twitter
mvn clean package

要让 Kafka Connect 去使用我们构建的连接器, 你要去修改配置文件。因为我们使用 Confluent 命令行,真实的配置文件是在 etc/schema-registry/connect-avro-distributed.properties,因此去修改它并增加如下内容:

plugin.path=/home/rmoff/kafka-connect-twitter/target/kafka-connect-twitter-0.2-SNAPSHOT.tar.gz

重启动 Kafka Connect:

confluent stop connect
confluent start connect

一旦你安装好插件,你可以很容易地去配置它。你可以直接使用 Kafka Connect 的 REST API ,或者创建你的配置文件,这就是我要在这里做的。如果你需要全部的方法,请首先访问 Twitter 来获取你的 API 密钥

{
 "name": "twitter_source_json_01",
 "config": {
   "connector.class": "com.github.jcustenborder.kafka.connect.twitter.TwitterSourceConnector",
   "twitter.oauth.accessToken": "xxxx",
   "twitter.oauth.consumerSecret": "xxxxx",
   "twitter.oauth.consumerKey": "xxxx",
   "twitter.oauth.accessTokenSecret": "xxxxx",
   "kafka.delete.topic": "twitter_deletes_json_01",
   "value.converter": "org.apache.kafka.connect.json.JsonConverter",
   "key.converter": "org.apache.kafka.connect.json.JsonConverter",
   "value.converter.schemas.enable": false,
   "key.converter.schemas.enable": false,
   "kafka.status.topic": "twitter_json_01",
   "process.deletes": true,
   "filter.keywords": "rickastley,kafka,ksql,rmoff"
 }
}

假设你写这些到 /home/rmoff/twitter-source.json,你可以现在运行:

$ confluent load twitter_source -d /home/rmoff/twitter-source.json

然后推文就从大家都喜欢的网络明星 [rick] 滚滚而来……

$ kafka-console-consumer --bootstrap-server localhost:9092 --from-beginning --topic twitter_json_01|jq '.Text'
{
  "string": "RT @rickastley: 30 years ago today I said I was Never Gonna Give You Up. I am a man of my word - Rick x https://t.co/VmbMQA6tQB"
}
{
  "string": "RT @mariteg10: @rickastley @Carfestevent Wonderful Rick!!\nDo not forget Chile!!\nWe hope you get back someday!!\nHappy weekend for you!!\n❤…"
}

KSQL

现在我们从 KSQL 开始 ! 马上去下载并构建它:

cd /home/rmoff
git clone https://github.com/confluentinc/ksql.git
cd /home/rmoff/ksql
mvn clean compile install -DskipTests

构建完成后,让我们来运行它:

./bin/ksql-cli local --bootstrap-server localhost:9092
                       ======================================
                       =      _  __ _____  ____  _          =
                       =     | |/ // ____|/ __ \| |         =
                       =     | ' /| (___ | |  | | |         =
                       =     |  <  \___ \| |  | | |         =
                       =     | . \ ____) | |__| | |____     =
                       =     |_|\_\_____/ \___\_\______|    =
                       =                                    =
                       =   Streaming SQL Engine for Kafka   =
Copyright 2017 Confluent Inc.

CLI v0.1, Server v0.1 located at http://localhost:9098

Having trouble? Type 'help' (case-insensitive) for a rundown of how things work!

ksql> 

使用 KSQL, 我们可以让我们的数据保留在 Kafka 主题上并可以查询它。首先,我们需要去告诉 KSQL 主题上的 数据模式 schema 是什么,一个 twitter 消息实际上是一个非常巨大的 JSON 对象, 但是,为了简洁,我们只选出其中几行:

ksql> CREATE STREAM twitter_raw (CreatedAt BIGINT, Id BIGINT, Text VARCHAR) WITH (KAFKA_TOPIC='twitter_json_01', VALUE_FORMAT='JSON');

Message  
----------------
Stream created

在定义的模式中,我们可以查询这些流。要让 KSQL 从该主题的开始展示数据(而不是默认的当前时间点),运行如下命令:

ksql> SET 'auto.offset.reset' = 'earliest';  
Successfully changed local property 'auto.offset.reset' from 'null' to 'earliest'

现在,让我们看看这些数据,我们将使用 LIMIT 从句仅检索一行:

ksql> SELECT text FROM twitter_raw LIMIT 1;  
RT @rickastley: 30 years ago today I said I was Never Gonna Give You Up. I am a man of my word - Rick x https://t.co/VmbMQA6tQB
LIMIT reached for the partition.  
Query terminated
ksql>

现在,让我们使用刚刚定义和可用的推文内容的全部数据重新定义该流:

ksql> DROP stream twitter_raw;
Message
--------------------------------
Source TWITTER_RAW was dropped

ksql> CREATE STREAM twitter_raw (CreatedAt bigint,Id bigint, Text VARCHAR, SOURCE VARCHAR, Truncated VARCHAR, InReplyToStatusId VARCHAR, InReplyToUserId VARCHAR, InReplyToScreenName VARCHAR, GeoLocation VARCHAR, Place VARCHAR, Favorited VARCHAR, Retweeted VARCHAR, FavoriteCount VARCHAR, User VARCHAR, Retweet VARCHAR, Contributors VARCHAR, RetweetCount VARCHAR, RetweetedByMe VARCHAR, CurrentUserRetweetId VARCHAR, PossiblySensitive VARCHAR, Lang VARCHAR, WithheldInCountries VARCHAR, HashtagEntities VARCHAR, UserMentionEntities VARCHAR, MediaEntities VARCHAR, SymbolEntities VARCHAR, URLEntities VARCHAR) WITH (KAFKA_TOPIC='twitter_json_01',VALUE_FORMAT='JSON');
Message
----------------
Stream created

ksql>

现在,我们可以操作和检查更多的最近的数据,使用一般的 SQL 查询:

ksql> SELECT TIMESTAMPTOSTRING(CreatedAt, 'yyyy-MM-dd HH:mm:ss.SSS') AS CreatedAt,\
EXTRACTJSONFIELD(user,'$.ScreenName') as ScreenName,Text \
FROM twitter_raw \
WHERE LCASE(hashtagentities) LIKE '%oow%' OR \
LCASE(hashtagentities) LIKE '%ksql%';  

2017-09-29 13:59:58.000 | rmoff | Looking forward to talking all about @apachekafka & @confluentinc’s #KSQL at #OOW17 on Sunday 13:45 https://t.co/XbM4eIuzeG

注意这里没有 LIMIT 从句,因此,你将在屏幕上看到 “continuous query” 的结果。不像关系型数据表中返回一个确定数量结果的查询,一个持续查询会运行在无限的流式数据上, 因此,它总是可能返回更多的记录。点击 Ctrl-C 去中断然后返回到 KSQL 提示符。在以上的查询中我们做了一些事情:

  • TIMESTAMPTOSTRING 将时间戳从 epoch 格式转换到人类可读格式。(LCTT 译注: epoch 指的是一个特定的时间 1970-01-01 00:00:00 UTC)
  • EXTRACTJSONFIELD 来展示数据源中嵌套的用户域中的一个字段,它看起来像:
{
"CreatedAt": 1506570308000,
"Text": "RT @gwenshap: This is the best thing since partitioned bread :) https://t.co/1wbv3KwRM6",
[...]
"User": {
    "Id": 82564066,
    "Name": "Robin Moffatt \uD83C\uDF7B\uD83C\uDFC3\uD83E\uDD53",
    "ScreenName": "rmoff",
    [...]
  • 应用断言去展示内容,对 #(hashtag)使用模式匹配, 使用 LCASE 去强制小写字母。(LCTT 译注:hashtag 是twitter 中用来标注线索主题的标签)

关于支持的函数列表,请查看 KSQL 文档

我们可以创建一个从这个数据中得到的流:

ksql> CREATE STREAM twitter AS \
SELECT TIMESTAMPTOSTRING(CreatedAt, 'yyyy-MM-dd HH:mm:ss.SSS') AS CreatedAt,\
EXTRACTJSONFIELD(user,'$.Name') AS user_Name,\
EXTRACTJSONFIELD(user,'$.ScreenName') AS user_ScreenName,\
EXTRACTJSONFIELD(user,'$.Location') AS user_Location,\
EXTRACTJSONFIELD(user,'$.Description') AS  user_Description,\
Text,hashtagentities,lang \
FROM twitter_raw ;

Message  
----------------------------  
Stream created and running  

ksql> DESCRIBE twitter;
Field            | Type  
------------------------------------  
ROWTIME          | BIGINT  
ROWKEY           | VARCHAR(STRING)  
CREATEDAT        | VARCHAR(STRING)  
USER_NAME        | VARCHAR(STRING)  
USER_SCREENNAME  | VARCHAR(STRING)  
USER_LOCATION    | VARCHAR(STRING)  
USER_DESCRIPTION | VARCHAR(STRING)  
TEXT             | VARCHAR(STRING)  
HASHTAGENTITIES  | VARCHAR(STRING)  
LANG             | VARCHAR(STRING)  
ksql>

并且查询这个得到的流:

ksql> SELECT CREATEDAT, USER_NAME, TEXT \
FROM TWITTER \
WHERE TEXT LIKE '%KSQL%';  

2017-10-03 23:39:37.000 | Nicola Ferraro | RT @flashdba: Again, I'm really taken with the possibilities opened up by @confluentinc's KSQL engine #Kafka https://t.co/aljnScgvvs

聚合

在我们结束之前,让我们去看一下怎么去做一些聚合。

ksql> SELECT user_screenname, COUNT(*) \
FROM twitter WINDOW TUMBLING (SIZE 1 HOUR) \
GROUP BY user_screenname HAVING COUNT(*) > 1;  

oracleace | 2  
rojulman | 2
smokeinpublic | 2  
ArtFlowMe | 2  
[...]

你将可能得到满屏幕的结果;这是因为 KSQL 在每次给定的时间窗口更新时实际发出聚合值。因为我们设置 KSQL 去读取在主题上的全部消息(SET 'auto.offset.reset' = 'earliest';),它是一次性读取这些所有的消息并计算聚合更新。这里有一个微妙之处值得去深入研究。我们的入站推文流正好就是一个流。但是,现有它不能创建聚合,我们实际上是创建了一个表。一个表是在给定时间点的给定键的值的一个快照。 KSQL 聚合数据基于消息的事件时间,并且如果它更新了,通过简单的相关窗口重申去操作后面到达的数据。困惑了吗? 我希望没有,但是,让我们看一下,如果我们可以用这个例子去说明。 我们将申明我们的聚合作为一个真实的表:

ksql> CREATE TABLE user_tweet_count AS \
SELECT user_screenname, count(*) AS  tweet_count \
FROM twitter WINDOW TUMBLING (SIZE 1 HOUR) \
GROUP BY user_screenname ;

Message  
---------------------------  
Table created and running

看表中的列,这里除了我们要求的外,还有两个隐含列:

ksql> DESCRIBE user_tweet_count;

Field           | Type  
-----------------------------------  
ROWTIME         | BIGINT  
ROWKEY          | VARCHAR(STRING)  
USER_SCREENNAME | VARCHAR(STRING)  
TWEET_COUNT     | BIGINT  
ksql>

我们看一下这些是什么:

ksql> SELECT TIMESTAMPTOSTRING(ROWTIME, 'yyyy-MM-dd HH:mm:ss.SSS') , \
ROWKEY, USER_SCREENNAME, TWEET_COUNT \
FROM user_tweet_count \
WHERE USER_SCREENNAME= 'rmoff';  

2017-09-29 11:00:00.000 | rmoff : Window{start=1506708000000 end=-} | rmoff | 2  
2017-09-29 12:00:00.000 | rmoff : Window{start=1506711600000 end=-} | rmoff | 4  
2017-09-28 22:00:00.000 | rmoff : Window{start=1506661200000 end=-} | rmoff | 2  
2017-09-29 09:00:00.000 | rmoff : Window{start=1506700800000 end=-} | rmoff | 4  
2017-09-29 15:00:00.000 | rmoff : Window{start=1506722400000 end=-} | rmoff | 2  
2017-09-29 13:00:00.000 | rmoff : Window{start=1506715200000 end=-} | rmoff | 6

ROWTIME 是窗口开始时间, ROWKEYGROUP BYUSER_SCREENNAME)加上窗口的组合。因此,我们可以通过创建另外一个衍生的表来整理一下:

ksql> CREATE TABLE USER_TWEET_COUNT_DISPLAY AS \
SELECT TIMESTAMPTOSTRING(ROWTIME, 'yyyy-MM-dd HH:mm:ss.SSS') AS WINDOW_START ,\
USER_SCREENNAME, TWEET_COUNT \
FROM user_tweet_count;

Message  
---------------------------  
Table created and running

现在它更易于查询和查看我们感兴趣的数据:

ksql> SELECT WINDOW_START ,  USER_SCREENNAME, TWEET_COUNT \
FROM USER_TWEET_COUNT_DISPLAY WHERE TWEET_COUNT> 20;  

2017-09-29 12:00:00.000 | VikasAatOracle | 22  
2017-09-28 14:00:00.000 | Throne_ie | 50  
2017-09-28 14:00:00.000 | pikipiki_net | 22  
2017-09-29 09:00:00.000 | johanlouwers | 22  
2017-09-28 09:00:00.000 | yvrk1973 | 24  
2017-09-28 13:00:00.000 | cmosoares | 22  
2017-09-29 11:00:00.000 | ypoirier | 24  
2017-09-28 14:00:00.000 | pikisec | 22  
2017-09-29 07:00:00.000 | Throne_ie | 22  
2017-09-29 09:00:00.000 | ChrisVoyance | 24  
2017-09-28 11:00:00.000 | ChrisVoyance | 28

结论

所以我们有了它! 我们可以从 Kafka 中取得数据, 并且很容易使用 KSQL 去探索它。 而不仅是去浏览和转换数据,我们可以很容易地使用 KSQL 从流和表中建立流处理。

如果你对 KSQL 能够做什么感兴趣,去查看:

记住,KSQL 现在正处于开发者预览阶段。 欢迎在 KSQL 的 GitHub 仓库上提出任何问题, 或者去我们的 community Slack group 的 #KSQL 频道。


via: https://www.confluent.io/blog/using-ksql-to-analyse-query-and-transform-data-in-kafka

作者:Robin Moffatt 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

学习使用 R 的 twitteR 和 leaflet 包, 你就可以把任何话题的推文定位画在地图上。

 title=

当我开始学习 R ,我也需要学习如何出于研究的目的地收集推特数据并对其进行映射。尽管网上关于这个话题的信息很多,但我发觉难以理解什么与收集并映射推特数据相关。我不仅是个 R 新手,而且对各种教程中技术名词不熟悉。但尽管困难重重,我成功了!在这个教程里,我将以一种新手程序员都能看懂的方式来攻略如何收集推特数据并将至展现在地图中。

创建应用程序

如果你没有推特帐号,首先你需要 注册一个。然后,到 apps.twitter.com 创建一个允许你收集推特数据的应用程序。别担心,创建应用程序极其简单。你创建的应用程序会与推特应用程序接口(API)相连。 想象 API 是一个多功能电子个人助手。你可以使用 API 让其它程序帮你做事。这样一来,你可以接入推特 API 令其收集数据。只需确保不要请求太多,因为推特数据请求次数是有限制 的。

收集推文有两个可用的 API 。你若想做一次性的推文收集,那么使用 REST API. 若是想在特定时间内持续收集,可以用 streaming API。教程中我主要使用 REST API。

创建应用程序之后,前往 Keys and Access Tokens 标签。你需要 Consumer Key (API key)、 Consumer Secret (API secret)、 Access Token 和 Access Token Secret 才能在 R 中访问你的应用程序。

收集推特数据

下一步是打开 R 准备写代码。对于初学者,我推荐使用 RStudio,这是 R 的集成开发环境 (IDE) 。我发现 RStudio 在解决问题和测试代码时很实用。 R 有访问该 REST API 的包叫 twitteR

打开 RStudio 并新建 RScript。做好这些之后,你需要安装和加载 twitteR 包:

install.packages("twitteR") 
#安装 TwitteR
library (twitteR) 
#载入 TwitteR

安装并载入 twitteR 包之后,你得输入上文提及的应用程序的 API 信息:

api_key <- "" 
 #在引号内放入你的 API key 
api_secret <- "" 
 #在引号内放入你的 API secret token 
token <- "" 
 #在引号内放入你的 token
token_secret <- "" 
 #在引号内放入你的 token secret

接下来,连接推特访问 API:

setup_twitter_oauth(api_key, api_secret, token, token_secret)

我们来试试让推特搜索有关社区花园和农夫市场:

tweets <- searchTwitter("community garden OR #communitygarden OR farmers market OR #farmersmarket", n = 200, lang = "en")

这个代码意思是搜索前 200 篇 (n = 200) 英文 (lang = "en") 的推文, 包括关键词 community gardenfarmers market 或任何提及这些关键词的话题标签。

推特搜索完成之后,在数据框中保存你的结果:

tweets.df <-twListToDF(tweets)

为了用推文创建地图,你需要收集的导出为 .csv 文件:

write.csv(tweets.df, "C:\Users\YourName\Documents\ApptoMap\tweets.csv") 
 #an example of a file extension of the folder in which you want to save the .csv file.

运行前确保 R 代码已保存然后继续进行下一步。.

生成地图

现在你有了可以展示在地图上的数据。在此教程中,我们将用一个 R 包 Leaflet 做一个基本的应用程序,这是一个生成交互式地图的热门 JavaScript 库。 Leaflet 使用 magrittr 管道运算符 (%>%), 因为其语法自然,易于写代码。刚接触可能有点奇怪,但它确实降低了写代码的工作量。

为了清晰起见,在 RStudio 打开一个新的 R 脚本安装这些包:

install.packages("leaflet")
install.packages("maps") 
library(leaflet)
library(maps)

现在需要一个路径让 Leaflet 访问你的数据:

read.csv("C:\Users\YourName\Documents\ApptoMap\tweets.csv", stringsAsFactors = FALSE)

stringAsFactors = FALSE 意思是保留信息,不将它转化成 factors。 (想了解 factors,读这篇文章"stringsAsFactors: An unauthorized biography", 作者 Roger Peng)

是时候制作你的 Leaflet 地图了。我们将使用 OpenStreetMap基本地图来做你的地图:

m <- leaflet(mymap) %>% addTiles()

我们在基本地图上加个圈。对于 lnglat,输入包含推文的经纬度的列名,并在前面加个~~longitude~latitude 指向你的 .csv 文件中与列名:

m %>% addCircles(lng = ~longitude, lat = ~latitude, popup = mymap$type, weight = 8, radius = 40, color = "#fb3004", stroke = TRUE, fillOpacity = 0.8)

运行你的代码。会弹出网页浏览器并展示你的地图。这是我前面收集的推文的地图:

 title=

带定位的推文地图,使用了 Leaflet 和 OpenStreetMap CC-BY-SA

虽然你可能会对地图上的图文数量如此之小感到惊奇,通常只有 1% 的推文记录了地理编码。我收集了总数为 366 的推文,但只有 10(大概总推文的 3%)是记录了地理编码的。如果你为得到记录了地理编码的推文而困扰,改变搜索关键词看看能不能得到更好的结果。

总结

对于初学者,把以上所有碎片结合起来,从推特数据生成一个 Leaflet 地图可能很艰难。 这个教程基于我完成这个任务的经验,我希望它能让你的学习过程变得更轻松。

(题图:琼斯·贝克. CC BY-SA 4.0. 来源: Cloud, Globe. Both CC0.)


作者简介:

Dorris Scott - Dorris Scott 是佐治亚大学的地理学博士生。她的研究重心是地理信息系统(GIS)、 地理数据科学、可视化和公共卫生。她的论文是在一个 GIS 系统接口将退伍军人福利医院的传统和非传统数据结合起来,帮助病人为他们的健康状况作出更为明朗的决定。


via: https://opensource.com/article/17/6/collecting-and-mapping-twitter-data-using-r

作者:Dorris Scott 译者:XYenChi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

在 Twitter 上分享的链接可以永久保存,用户不用担心。

 title=

互联网是永远的,当发生下面的情况的就不是了。 “链接腐烂” - 当页面移动或者站点脱机,随着时间的流逝,到网站的有效链接就会断开 - 对于尝试在线做研究的人来说,这是一个真正的问题。 互联网档案馆 Internet Archive 通过在它的“ 时光机 Wayback Machine ”中提供提交的内容来帮助解决这个问题。

当然,困难的是让人们记得提交档案链接。

这就是 Parker Higgins 的新 Twitter 机器人所切入的地方。@LinkArchiver 会自动提交关注了 互联网档案馆 Internet Archive 的帐户所提交的链接。如果一个 Twitter 用户关注了 @LinkArchiver,它会回关,即使用户取消关注机器人,它也会继续添加链接。这意味着在 Twitter 上共享的链接可以永久保存,用户不用担心。

无需留意这个方面对 Higgins 非常有吸引力。他对 Opensource.com 说:“我对整个装置的被动程度非常在意。如果你依靠人们选择什么是重要的来存档,你会错过很多最重要的东西,只要抓取每个发表链接的副本,这个机器人应该有助于确保我们不会错过上下文。”

在最初开发机器人之后,Higgins 联系了 互联网档案馆 Internet Archive 。他对自动化造成问题的担忧很快被消除。尽管他在请求时给 API 请求用了一个自定义的用户代理字符串,但是他说:“他们处理的流量实际上是个舍入错误。”扩展性的问题在 Twitter 方面:其服务限制了帐户的关注者数量和新关注者的比例。这限制了 LinkArchiver 的单个实例的能力。

幸运的是,LinkArchiver 以 AGPLv3 授权在 GitHub 上发布。

有了一台小的服务器和一个 Twitter 账号, 任何人都可以运行这个机器人。Higgins 设想人们运行一个关注特定的兴趣或社交圈子的 LinkArchiver 的实例。“发生在我身上的一件事是,你可以关闭回关行为,并关注特定的组或者兴趣。例如,机器人可以关注一群朋友或同学,或主要媒体,或每一个美国参议员和代表,并存档他们发表的 tweet。”

这不是 Higgins 第一次写 Twitter 机器人:@securethenews@pomological 以及受欢迎的 @choochoobot 是他之前的作品。这些机器人都是只写的。 LinkArchiver 是他开发的第一个互动机器人,这需要学习几种新技能。这是 Higgins 参与 Recurse Center 的一部分,这是为程序员进行的为期 12 周的活动。

Higgins 鼓励大家的拉取请求以及其他的 LinkArchiver 机器人实例。

(题图:Beatrice Murch 拍摄的 Inernet Archive 总部; CC BY (on Flickr))


作者简介:

Ben Cotton - Ben Cotton 是一个受训过的气象学家和一名高性能计算机工程师。Ben 在 Cycle Computing 做技术传教士。他是 Fedora 用户和贡献者,合作创办当地的一个开源集会,是一名开源倡议者和软件自由机构的支持者。他的推特 (@FunnelFiasco)


via: https://opensource.com/article/17/7/linkarchiver-automatically-submits-links-internet-archive

作者:Ben Cotton 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

过去我们曾经发布过一些关于 FinagleManhattan 这些项目的文章,还写过一些针对大型事件活动的架构优化的文章,例如天空之城、超级碗、2014 世界杯、全球新年夜庆祝活动等。在这篇基础设施系列文章中,我主要聚焦于 Twitter 的一些关键设施和组件。我也会写一些我们在系统的扩展性、可靠性、效率方面的做过的改进,例如我们基础设施的历史,遇到过的挑战,学到的教训,做过的升级,以及我们现在前进的方向等等。

天空之城:2013 年 8 月 2 日,宫崎骏的《 天空之城 Castle in the Sky 》在 NTV 迎来其第 14 次电视重播,剧情发展到高潮之时,Twitter 的 TPS(Tweets Per Second)也被推上了新的高度——143,199 TPS,是平均值的 25 倍,这个记录保持至今。-- LCTT 译注

数据中心的效率优化

历史

当前 Twitter 硬件和数据中心的规模已经超过大多数公司。但达到这样的规模不是一蹴而就的,系统是随着软硬件的升级优化一步步成熟起来的,过程中我们也曾经犯过很多错误。

有个一时期我们的系统故障不断。软件问题、硬件问题,甚至底层设备问题不断爆发,常常导致系统运营中断。出现故障的地方存在于各个方面,必须综合考虑才能确定其风险和受到影响的服务。随着 Twitter 在客户、服务、媒体上的影响力不断扩大,构建一个高效、可靠的系统来提供服务成为我们的战略诉求。

Twitter系统故障的界面被称为 失败鲸 Fail Whale ,如下图 -- LCTT 译注

Fail Whale

挑战

一开始,我们的软件是直接安装在服务器,这意味着软件可靠性依赖硬件,电源、网络以及其他的环境因素都是威胁。这种情况下,如果要增加容错能力,就需要统筹考虑这些互不关联的物理设备因素及在上面运行的服务。

最早采购数据中心方案的时候,我们都还是菜鸟,对于站点选择、运营和设计都非常不专业。我们先直接托管主机,业务增长后我们改用租赁机房。早期遇到的问题主要是因为设备故障、数据中心设计问题、维护问题以及人为操作失误。我们也在持续迭代我们的硬件设计,从而增强硬件和数据中心的容错性。

服务中断的原因有很多,其中硬件故障常发生在服务器、机架交换机、核心交换机这地方。举一个我们曾经犯过的错误,硬件团队最初在设计服务器的时候,认为双路电源对减少供电问题的意义不大 -- 他们真的就移除了一块电源。然而数据中心一般给机架提供两路供电来提高冗余性,防止电网故障传导到服务器,而这需要两块电源。最终我们不得不在机架上增加了一个 ATS 单元( 交流切换开关 AC transfer switch )来接入第二路供电。

提高系统的可靠性靠的就是这样的改进,给网络、供电甚至机房增加冗余,从而将影响控制到最小范围。

我们学到的教训以及技术的升级、迁移和选型

我们学到的第一个教训就是要先建模,将可能出故障的地方(例如建筑的供电和冷却系统、硬件、光纤网络等)和运行在上面的服务之间的依赖关系弄清楚,这样才能更好地分析,从而优化设计提升容错能力。

我们增加了更多的数据中心提升地理容灾能力,减少自然灾害的影响。而且这种站点隔离也降低了软件的风险,减少了例如软件部署升级和系统故障的风险。这种多活的数据中心架构提供了 代码灰度发布 staged code deployment 的能力,减少代码首次上线时候的影响。

我们设计新硬件使之能够在更高温度下正常运行,数据中心的能源效率因此有所提升。

下一步工作

随着公司的战略发展和运营增长,我们在不影响我们的最终用户的前提下,持续不断改进我们的数据中心。下一步工作主要是在当前能耗和硬件的基础上,通过维护和优化来提升效率。

硬件的效率优化

历史和挑战

我们的硬件工程师团队刚成立的时候只能测试市面上现有硬件,而现在我们能自己定制硬件以节省成本并提升效率。

Twitter 是一个很大的公司,它对硬件的要求对任何团队来说都是一个不小的挑战。为了满足整个公司的需求,我们的首要工作是能检测并保证购买的硬件的品质。团队重点关注的是性能和可靠性这两部分。对于硬件我们会做系统性的测试来保证其性能可预测,保证尽量不引入新的问题。

随着我们一些关键组件的负荷越来越大(如 Mesos、Hadoop、Manhattan、MySQL 等),市面上的产品已经无法满足我们的需求。同时供应商提供的一些高级服务器功能,例如 Raid 管理或者电源热切换等,可靠性提升很小,反而会拖累系统性能而且价格高昂,例如一些 Raid 控制器价格高达系统总报价的三分之一,还拖累了 SSD 的性能。

那时,我们也是 MySQL 数据库的一个大型用户。SAS( 串行连接 SCSI Serial Attached SCSI )设备的供应和性能都有很大的问题。我们大量使用 1U 规格的服务器,它的磁盘和回写缓存一起也只能支撑每秒 2000 次的顺序 IO。为了获得更好的效果,我们只得不断增加 CPU 核心数并加强磁盘能力。我们那时候找不到更节省成本的方案。

后来随着我们对硬件需求越来越大,我们成立了一个硬件团队,从而自己来设计更便宜更高效的硬件。

关键技术变更与选择

我们不断的优化硬件相关的技术,下面是我们采用的新技术和自研平台的时间轴。

  • 2012 - 采用 SSD 作为我们 MySQL 和 Key-Value 数据库的主要存储。
  • 2013 - 我们开发了第一个定制版 Hadoop 工作站,它现在是我们主要的大容量存储方案。
  • 2013 - 我们定制的解决方案应用在 Mesos、TFE( Twitter Front-End )以及缓存设备上。
  • 2014 - 我们定制的 SSD Key-Value 服务器完成开发。
  • 2015 - 我们定制的数据库解决方案完成开发。
  • 2016 - 我们开发了一个 GPU 系统来做模糊推理和训练机器学习。

学到的教训

硬件团队的工作本质是通过做取舍来优化 TCO(总体拥有成本),最终达到达到降低 CAPEX(资本支出)和 OPEX(运营支出)的目的。概括来说,服务器降成本就是:

  1. 删除无用的功能和组件
  2. 提升利用率

Twitter 的设备总体来说有这四大类:存储设备、计算设备、数据库和 GPU 。 Twitter 对每一类都定义了详细的需求,让硬件工程师更针对性地设计产品,从而优化掉那些用不到或者极少用的冗余部分。例如,我们的存储设备就专门为 Hadoop 优化过,设备的购买和运营成本相比于 OEM 产品降低了 20% 。同时,这样做减法还提高了设备的性能和可靠性。同样的,对于计算设备,硬件工程师们也通过移除无用的特性获得了效率提升。

一个服务器可以移除的组件总是有限的,我们很快就把能移除的都扔掉了。于是我们想出了其他办法,例如在存储设备里,我们认为降低成本最好的办法是用一个节点替换多个节点,并通过 Aurora/Mesos 来管理任务负载。这就是我们现在正在做的东西。

对于这个我们自己新设计的服务器,首先要通过一系列的标准测试,然后会再做一系列负载测试,我们的目标是一台新设备至少能替换两台旧设备。最大的性能提升来自增加 CPU 的线程数,我们的测试结果表示新 CPU 的 单线程能力提高了 20~50% 。同时由于整个服务器的线程数增加,我们看到单线程能效提升了 25%。

这个新设备首次部署的时候,监控发现新设备只能替换 1.5 台旧设备,这比我们的目标低了很多。对性能数据检查后发现,我们之前对负载特性的一些假定是有问题的,而这正是我们在做性能测试需要发现的问题。

对此我们硬件团队开发了一个模型,用来预测在不同的硬件配置下当前 Aurora 任务的填充效率。这个模型正确的预测了新旧硬件的性能比例。模型还指出了我们一开始没有考虑到的存储需求,并因此建议我们增加 CPU 核心数。另外,它还预测,如果我们修改内存的配置,那系统的性能还会有较大提高。

硬件配置的改变都需要花时间去操作,所以我们的硬件工程师们就首先找出几个关键痛点。例如我们和 SRE( 网站可靠性工程师 Site Reliability Engineer )团队一起调整任务顺序来降低存储需求,这种修改很简单也很有效,新设备可以代替 1.85 个旧设备了。

为了更好的优化效率,我们对新硬件的配置做了修改,只是扩大了内存和磁盘容量就将 CPU 利用率提高了20% ,而这只增加了非常小的成本。同时我们的硬件工程师也和合作生产厂商一起为那些服务器的最初出货调整了物料清单。后续的观察发现我们的自己的新设备实际上可以代替 2.4 台旧设备,这个超出了预定的目标。

从裸设备迁移到 mesos 集群

直到 2012 年为止,软件团队在 Twitter 开通一个新服务还需要自己操心硬件:配置硬件的规格需求,研究机架尺寸,开发部署脚本以及处理硬件故障。同时,系统中没有所谓的“服务发现”机制,当一个服务需要调用一个另一个服务时候,需要读取一个 YAML 配置文件,这个配置文件中有目标服务对应的主机 IP 和端口信息(预留的端口信息是由一个公共 wiki 页面维护的)。随着硬件的替换和更新,YAML 配置文件里的内容也会不断的编辑更新。在缓存层做修改意味着我们可以按小时或按天做很多次部署,每次添加少量主机并按阶段部署。我们经常遇到在部署过程中 cache 不一致导致的问题,因为有的主机在使用旧的配置有的主机在用新的。有时候一台主机的异常(例如在部署过程中它临时宕机了)会导致整个站点都无法正常工作。

在 2012/2013 年的时候,Twitter 开始尝试两个新事物:服务发现(来自 ZooKeeper 集群和 Finagle 核心模块中的一个库)和 Mesos(包括基于 Mesos 的一个自研的计划任务框架 Aurora ,它现在也是 Apache 基金会的一个项目)。

服务发现功能意味着不需要再维护一个静态 YAML 主机列表了。服务或者在启动后主动注册,或者自动被 mesos 接入到一个“服务集”(就是一个 ZooKeeper 中的 znode 列表,包含角色、环境和服务名信息)中。任何想要访问这个服务的组件都只需要监控这个路径就可以实时获取到一个正在工作的服务列表。

现在我们通过 Mesos/Aurora ,而不是使用脚本(我们曾经是 Capistrano 的重度用户)来获取一个主机列表、分发代码并规划重启任务。现在软件团队如果想部署一个新服务,只需要将软件包上传到一个叫 Packer 的工具上(它是一个基于 HDFS 的服务),再在 Aurora 配置上描述文件(需要多少 CPU ,多少内存,多少个实例,启动的命令行代码),然后 Aurora 就会自动完成整个部署过程。 Aurora 先找到可用的主机,从 Packer 下载代码,注册到“服务发现”,最后启动这个服务。如果整个过程中遇到失败(硬件故障、网络中断等等), Mesos/Aurora 会自动重选一个新主机并将服务部署上去。

Twitter 的私有 PaaS 云平台

Mesos/Aurora 和服务发现这两个功能给我们带了革命性的变化。虽然在接下来几年里,我们碰到了无数 bug ,伤透了无数脑筋,学到了分布式系统里的无数教训,但是这套架还是非常赞的。以前大家一直忙于处理硬件搭配和管理,而现在,大家只需要考虑如何优化业务以及需要多少系统能力就可以了。同时,我们也从根本上解决了 Twitter 之前经历过的 CPU 利用率低的问题,以前服务直接安装在服务器上,这种方式无法充分利用服务器资源,任务协调能力也很差。现在 Mesos 允许我们把多个服务打包成一个服务包,增加一个新服务只需要修改配额,再改一行配置就可以了。

在两年时间里,多数“无状态”服务迁移到了 Mesos 平台。一些大型且重要的服务(包括我们的用户服务和广告服务系统)是最先迁移上去的。因为它们的体量巨大,所以它们从这些服务里获得的好处也最多,这也降低了它们的服务压力。

我们一直在不断追求效率提升和架构优化的最佳实践。我们会定期去测试公有云的产品,和我们自己产品的 TCO 以及性能做对比。我们也拥抱公有云的服务,事实上我们现在正在使用公有云产品。最后,这个系列的下一篇将会主要聚焦于我们基础设施的体量方面。

特别感谢 Jennifer FraserDavid BarrGeoff PapilionMatt SingerLam Dong 对这篇文章的贡献。


via: https://blog.twitter.com/2016/the-infrastructure-behind-twitter-efficiency-and-optimization

作者:mazdakh 译者:eriwoon 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出