在Grammarly的生产环境中运行Lisp


Grammarly 是一个应用程序,数百万人使用它来检查他们的电子邮件、论文、笔记等的语法。
该产品建立在核心语法引擎之上,每秒可处理一千多个句子,可水平扩展,并且已在生产中可靠地服务了近三年。
该引擎是用Common Lisp 编写的,博客文章介绍了 Grammarly 如何在生产中运行 Lisp 以及他们在这样做时遇到的一些棘手的错误。
 
Lisp 是一种用于构建生产系统的非常实用的语言。事实上,那里有许多 Lisp 系统:当你在 Hipmunk 上搜索机票或在伦敦乘坐地铁时,就会调用 Lisp 程序。
我们的 Lisp 服务在概念上是一个经典的 AI 应用程序,它基于语言学家和研究人员创建的大量知识进行操作。它主要是一个 CPU 密集型程序,它是我们网络中计算资源的最大消费者之一。
我们在部署到 AWS 的库存 Linux 映像上运行这些服务。我们  在大多数开发人员的机器上使用SBCL 进行生产部署和 CCL 。
 
Lisp 的优点之一是,您可以从几个具有不同优点和缺点的成熟实现中进行选择:在我们的案例中,我们针对服务器上的处理速度和开发环境中的编译速度进行了优化(原因是对我们至关重要的部分将在后面的部分中描述)。
 
在 Grammarly,我们使用多种编程语言来开发我们的服务:除了 JVM 语言和 JavaScript,我们还使用 Erlang、Python 和 Go 进行开发。适当的服务封装使我们能够使用最有意义的任何语言和平台。维护是有成本的,但我们重视选择和自由,而不是规则和流程。
我们还尝试依赖简单的与语言无关的基础设施工具。这种方法使我们免于在我们的平台中集成这个技术动物园的很多麻烦。
关于 Lisp 的常见抱怨之一是生态系统中没有库。如您所见,仅在此示例中使用了五个库来进行编码、压缩、获取 Unix 时间和套接字连接等操作:

(defun graylog (message &key level backtrace file line-no)
  (let ((msg (salza2:compress-data
              (babel:string-to-octets
               (json:encode-json-to-string #{
                 :version "1.0"
                 :facility
"lisp"
                 :host *hostname*
                 :|short_message| message
                 :|full_message| backtrace
                 :timestamp (local-time:timestamp-to-unix (local-time:now))
                 :level level
                 :file file
                 :line line-no
                })
               :encoding :utf-8)
              'salza2:zlib-compressor)))
    (usocket:socket-send (usocket:socket-connect
                          *graylog-host* *graylog-port*
                          :protocol :datagram :element-type '(unsigned-byte 8))
                         msg (length msg))))

 
我们在 Grammarly 平台中尝试遵循的另一个原则是不同服务的最大解耦,以确保水平可扩展性和操作独立性。这样,我们就不需要在核心服务的关键路径中与数据库进行交互。然而,我们确实使用 MySQL、Postgres、Redis 和 Mongo 作为内部存储,并且我们已经成功地使用 CLSQL、  postmodern、  cl-redis和 cl-mongo 从 Lisp 端访问它们。
我们依靠 Quicklisp 来管理外部依赖项,并使用一个简单的系统将库源代码与我们的内部库或分支的项目捆绑在一起。Quicklisp 存储库拥有一千多个 Lisp 库——这不是一个令人兴奋的数字,但足以满足我们所有的生产需求。
为了部署到生产环境中,我们使用通用堆栈:应用程序由 Jenkins 测试和捆绑,由 Rundeck 放在服务器上,并由 Upstart 作为常规 Unix 进程在那里运行。
总的来说,我们将 Lisp 应用程序集成到云世界中所面临的问题与我们在使用许多其他技术时遇到的问题并没有根本不同。
 
更多点击标题