dragoninasia2014 2018-11-12 15:01
浏览 72

为可扩展的Go应用程序提供Redis客户端的最佳方法

I'm using redigo in an application and I'm wondering how my services should interface with Redis.

Wikipedia has this to say about thread-safety:

Thread safety is a computer programming concept applicable to multi-threaded code. Thread-safe code only manipulates shared data structures in a manner that ensures that all threads behave properly and fulfill their design specifications without unintended interaction.

What I interpret this to mean is that if a data-structure needs to be accessed by multiple clients (hundreds, thousands if not millions in today's micro-service world) thread-safety is the way in which we ensure that state is correctly preserved in the system regardless of which client accesses the data and when. This means resolving access priority (which client got there first), ensuring lock on mutation (only one client can write at a time) while promoting concurrency (many clients can read the data if there is no change).

From what I've gathered, a redigo client can be used by multiple "goroutines" (or threads) concurrently. That leads me to believe that a singleton implementation like I'm familiar with in Java should suffice.

I see examples, e.g., here and here, where Redis connections (pools) are simply created in the main method and passed in to various redigo functions. That doesn't seem like the most robust way to get things done, although they do appear to be following the singleton pattern. (Understandably the second post is really just a quick n'dirty API.)

I would do it like this:

  1. In the main function call init which returns a redigo pool.

  2. Create handler functions (controllers) that accept a pool as a param (a sort of "dirty" dependency injection).

This would (I think) ensure that only a single pool is ever created.

Alternatively, is there any reason why I can't create a pool (client) every time I want to access the data store? If the client is killed after the transaction is complete, is there any issue with spinning up a new pool every time a handler receives a request?

  • 写回答

1条回答 默认 最新

  • duanpie2414 2018-11-12 19:40
    关注

    Correct answer is already provided in comments, although I still want to add my 5 cents.

    Your question mixes up two concepts - concurrency and resource pool.

    Concurrent code makes sure that several execution flows safely work inside the same application using shared memory. In our example we have multiple http requests from our users and handlers code for these requests that is executed concurrently. DB connection is part of that flow and required for request execution.

    Concurrent code should be abble to use DB connection and open/close connection if necessary.

    Although, concurrency has nothing to do with rules defining how many connections should be opened at any given time and how these connections should be reused/shared:

    • Someone can create DB connection per request and that code is concurrent.
    • Someone can use some shared DB connection(s) and that code is concurrent as long as multiple requests does not interfere with each other. What is typically achieved with memory locks.

    Connection Pool, from other side, is pattern that provides efficient way to handle DB connections. Why managing connections lifetime is important:

    1. Connection is expensive to open
    2. Connection expensive to keep alive without using as database can keep only limited number of open connections.

    With connection pool you can control:

    1. How many connection are always open - warm up slow resource
    2. Max number of open connection - prevent opening too many connections
    3. Connection timeout - balancing between connections reuse and releasing not used resources

    Maintaining connection or connection pool per request does not allow efficient connections reuse. Every request is slowed down with connection opening overhead, spike in traffic will cause opening too many connections and etc.

    Typically application has one connection pool shared between all requests.

    Sometimes, developers create several pools for different types of connections. For example one pool for transactional operations and one for reports.

    评论

报告相同问题?

悬赏问题

  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题