在Grammarly的生產環境中執行Lisp

banq發表於2022-02-16

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 應用程式整合到雲世界中所面臨的問題與我們在使用許多其他技術時遇到的問題並沒有根本不同。

 

更多點選標題

相關文章