翻译系统 5/14/2019更新

第二版 (5/14/2019更新)

React component example

Confirm Amount

数据库设计

Language Resource Table Schema
Key, OriginContent, LastUpdated, ContentLangId1, LastUpdatedLangId1, ContentLangId2, LastUpdatedLangId2, ...
Key一定是要有比较规范的name space, 避免出现同一个key被不同的developper使用修改。

Task Table Schema
Key, OriginContent, LastUpdated, LanguageId, TranslatorId, status, HtmlFileLink, prioritiy

一种做法: 网页修改完毕不等翻译完成就上线。

网页文件修改之后一种做法是直接deploy,用户load页面的时候会产生翻译请求。
这种做法的考虑基于是很多时候某个页面在某种语言很少会出现,没必要等全部翻译完再上线。
根据用户load的时候如果某个key找不到,就会自动产生一个translation request, 同时用英语做为fall back。 一个key被Request的次数越多他的优先级越高,

API:

GetTranlantion(key, originContent, url)
this API call may make internal call: RequestTranslatorService(key, originContent, url)

单词内容有变化? OriginalContent修改的情况

如果这个key的英文改了: 在translation的时候就会发现送过去的originalLanguageContent的数据库里的不一致!这种情况要做三件事情: 1。 更新数据库里的original content, 2。 更新originalContent 的last update time。 3. send update translation request.

如果翻译还没更新又来访问这个request了, 虽然内容一致,但翻译和原文的timestamp顺序相反,这时仍然使用旧的翻译,同时再发一次translation request.

updateTranslationAsOriginalContentUpdated(key, previousContent, newContent)

如果嫌慢(因为要写很多个任务)可以丢到一个message Queue里面去异步执行。

key , originalcontent, translantion.

如何翻译

getTranslation(key, OriginalLanguageContent, languageId)

如果找到,originalContent一致并且翻译的timestamp比数据库里originalContent的时间stamp要晚,则直接返回。如果找到但内容不一致/timestamp不对 则refer to original content修改的情况。

如果找不到就fall back为英语,同时增加一个翻译请求。这个翻译请求如果已经在task list里了,就更新优先级, 如果不在, 就新建。

如何给翻译员分配任务

根据翻译员的语言种类,从当前任务列表里先择优先级最高的一组翻译,最好是据有相同key前缀的(一般优先级也会相同, 因为一个页面里的key是同时更新优先级的)。同时更新Task table把当前任务设为pending,翻译员id也设置上. 这样别的翻译员就不会去拿同一个task。 可以再增加一个field记一下任务是什么时候开始的。如果一段时间任务并没有完成,则自动重新变成available.

getTranslationTask(languageId, amount, translatorId);

翻译员如何更新翻译

Api: enterTranslation(key, languageId, translated content, translatetimeStamp, originContentTimeStamp)

在更新数据库时候先check一下数据库里original content的time stamp, 如果翻译人员提交的original content的timestamp比较老, 则拒绝这次更新,返回outdated originalContent Exception.

如果更新成功, 则把更新的信息broadcast给所有存有cache的web服务器。也可以定期推送。

另外一种做法翻译完再上线。

另外一种做法是网页修改之后,直接extract新的key和修改过的key value pair. 这些key不翻译完新版网页就不上线。

Api: ExtractForTranslation(fileName) return a jobId

Using this jobId, the developper can see how much content has been already translated

全部翻译完成后翻译官把整个翻译的package发过来。发过来之后由系统统一deploy。但这样会delay上线速度。 此时翻译官也不会直接把翻译输入数据库。因为新网页还没上线, 翻译先上线会造成数据不一致。

Scale

可以把两张表都放到数据库里面。 Lanaguage Resource Table直接在每个webserver上做cache。如果数据库有更新,数据库服务器就会notify 其他所有的webserver更新cache。可以每十分钟做一次。

如何Sharding:

由于数据量不大,本身不一定需要sharding。可以按语言和对应的location sharding。

Indexing

LanguageResource直接按key查+就可以了, 本身就有index, 不需要再建index。

对于task Table要按 languageId + 状态 建 index,

task Table的primary index是 key + languageId,

每天半夜12点可以更新一下优先级,让所有的优先级衰减。删掉那些低于某些threhold的值。

-----------------------------我写的翻译系统第二版到这里结束-------------------------------------------------------------

参考文献:

相关的官方技术博客
https://medium.com/airbnb-engineering/launching-airbnb-jp-in-record-time-52f8b0af965d
技术文档 https://airbnb.io/polyglot.js/
其他 https://www.jiuzhang.com/qa/5054/ https://github.com/donnemartin/system-design-primer

4S 分析大法

Scenario:

前端人员使用一种语言(比如英语)设计前端。
menu label, 描述,免责条款,
前端人员release 英文版网页或内容 ==》 触发翻译系统extract 翻译事件 :翻译系统分析英文版文件,对比哪些句子/内容已经翻译过了,哪些句子/内容需要新翻译。==》 extract出新句子分发给翻译员。==》翻译员完成翻译任务之后返回给翻译系统。翻译系统输出多种语言包。

系统可以分为两种实现形式:

如果是网页更新比较慢而且是一组静态网页的话。

1。前端人员 2。 网页分析服务。 3数据库 4。 Combine 服务 5。翻译员。
这样的话,所有的内容在创建的时候都立马翻译好,可能有几个小时到一两天的delay。
这种的缺点是所有语言版本的发布会比较慢,因为所有内容都要翻译。

如果是像Airbnb这样的动态生成的网页(数据都是数据库里调出来的)

前端人员修改网页的时候,可以在修改完网页时自动发一个翻译的request 通知系统去翻译,但可能网页还没翻译完就上线了。
用户输入airbnb.cn网站地址,根据用户的地理语言信息,webserver在生成网页的时候发一个translate request. 把网页里对应的标签转换成相应的语言再返回给用户。相当于一个实时的翻译系统。不需要等待页面全部翻译完成再上线。如果一个词在本地cache里,先查本地cache, 如果不在本地cache,则可以跨过网络去查数据库的cache,如果数据库的cache里面也没有,则去数据库里找,找不到就用默认语言并且去待翻译数据库里面给该key增加一下优先级。 一个key被request的次数越多,它的优先级越高。

翻译人员从“待翻译数据库” 里拿出当前优先级最高的词, 翻译,输入系统。

API

GetTranslate(key, default, locale)
EnterTranslatedVersion(key, default, value, locale)
如果要改key 和default的话, 可以增加一个api, updateTranslate(key, new default, locale)

需要设计多牛的系统

怎么估算size??
还真不知道。 算一下有多少网页:每个网页有多少单词??还得再想想

Service

Translate Service
Translator task service

Client     -->        webServer 
                            |
                            v
Front End -> Translate Service ->    DataBase
                                         ^
                                         |
                                         v
Translator   <-->       Translate Task Service 

Storage

Data model

Translation Table

用什么数据库? Redis (内存型), Cassandra, SQL + Memcached

Redis是纯粹的key -value pair: 如果用Redis
Key:Key + Locale, Value : content in language of locale + time stamp

如果用Cassandra, 三层结构。
Schema:
Row Key : Key ;
Column Key: Locale
Value: content in some language + time stamp
读取的时候要用Key + locale去读。

也可以用SQL,反正是读多写少,大不了用cache优化一下。
SQL也行。。。因为哪儿哪么多访问量

Task Table

这个量级很小,一个SQL就足够了。
Schema如下
Key,Original Language, To Language,优先级, status,

Working solution

前端人员把 key, English

优化:

按优先级排序,如果一个key被call的次数越多,优先级越高。 如果一个key四天都没有被call过,则自动清除出队列。

加速 优化perf

在Web Server端放一些Cache,有问题先查本地的cache,查不到再找DB。
建index, 只需要根据key 和locale建一个composite primary index就可以了。
bloom filter : 如果一个key不在bloom filter里面,则肯定不用找了。

关键问题: 如果DB更新了,如何第一时间更新那么多server:

DB主动发送push notification给Web Server.
需要设计TTL吗? 最好这样,不然如果某些push notification某种原因没有收到,就跪了。

Sharding

如果需要Sharding,则可以按语言按距离按国家Sharding。
非要按Hash code sharding的话,sharding key就是我们的key。其实并不需要sharding,一台机器是可以搞定的。
Consistent hashing 的概念
按String做为sharding key

Cache

Cache thru 和Cache aside都可以。但重要的是在服务器端直接cache, 就不用每次访问数据库了。

前端程序员不受后端设计的影响。

前端用key,和 value写在html里面。

translator有另一个portal输入翻译而且能马上看到效果

把对应的html存下来,直接调存下来的html显示。

再来就是有时候translator翻译错了修改之后怎么样才能更快的让大家看见(如果你有cache的话)

Broadcast,Server和DB 保持一个长链接,有新的变化立马通知。

你可能感兴趣的:(翻译系统 5/14/2019更新)