翻译系统 5/14/2019更新

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

React component example

<LanguageResource key = checkout.cfmMoney>Confirm Amount</LanguageResource>

数据库设计

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 保持一个长链接,有新的变化立马通知。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容