diff --git a/README.md b/README.md index 1cfa00df..5e2c1add 100644 --- a/README.md +++ b/README.md @@ -1,155 +1,21 @@ # presto-gateway -A load balancer / proxy / gateway for presto compute engine. - -## Getting Started - -### Build and run -run `mvn clean install` to build `presto-gateway` -Edit the [config file](gateway/src/main/resources/config.yml.template) and update backend urls +A load balancer / proxy / gateway for presto compute engine. -``` -cd gateway/target/ -java -jar gateway-{{VERSION}}-jar-with-dependencies.jar server ../src/presto-gateway/gateway/src/main/resources/config.yml.template -``` -Now you can access load balanced presto at localhost:8080 port. We will refer to this as `prestogateway.lyft.com` - -### Query History UI - check query plans etc. -PrestoGateway records history of recent queries and displays links to check query details page in respective presto cluster. -![prestogateway.lyft.com](docs/assets/prestogateway_query_history.png) +## Getting started -### Adhoc vs Scheduled query routing -In the [config](gateway/src/main/resources/config.yml.template) -you can specify if a backend cluster is a part of a routing group. -If not specified, cluster will be part of `adhoc` routing group by default. +Presto Gateway can be deployed as a standalone stateless service or with high availability and external database. For help with setting up a standalone gateway service, please visit [Standalone Gateway](/gateway/#standalone-gateway). For help with setting up a gateway service with high availability, please visit [Gateway-HA](/gateway-ha#gateway-ha). -PrestoGateway router will route any request to `scheduled` group of clusters if request contains header `X-Presto-Routing-Group: scheduled` and there are clusters present with config `routingGroup: scheduled`. +For further information regarding the design of the gateway, please visit the [Gateway Design Document](/docs/design.md) -If no matching `routingGroup` found, router will route to `adhoc` group of clusters. Please make sure there are clusters under `adhoc` routing group. ## Gateway API -### Get all backends behind the gateway - -`curl -X GET prestogateway.lyft.com/gateway/backend/all | python -m json.tool` -``` -[ - { - "active": true, - "includeInRouter": true, - "localPort": 8081, - "name": "presto1", - "proxyTo": "http://presto1.lyft.com", - "routingGroup": "adhoc" - }, - { - "active": true, - "includeInRouter": true, - "localPort": 8083, - "name": "presto3", - "proxyTo": "http://presto3.lyft.com", - "routingGroup": "adhoc" - }, - { - "active": true, - "includeInRouter": true, - "localPort": 8082, - "name": "presto2", - "proxyTo": "http://presto2.lyft.com", - "routingGroup": "adhoc" - } -] -``` - -### Get active backends behind the Gateway - -`curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool` -``` -[ - { - "active": true, - "includeInRouter": true, - "localPort": 8081, - "name": "presto1", - "proxyTo": "http://presto1.lyft.com", - "routingGroup": "adhoc" - }, - { - "active": true, - "includeInRouter": true, - "localPort": 8082, - "name": "presto2", - "proxyTo": "http://presto2.lyft.com", - "routingGroup": "adhoc" - }, - { - "active": true, - "includeInRouter": true, - "localPort": 8083, - "name": "presto3", - "proxyTo": "http://presto3.lyft.com", - "routingGroup": "adhoc" - } -] -``` -### Deactivate a backend - -`curl -X POST prestogateway.lyft.com/gateway/backend/deactivate/presto2` - -Verify this by calling get active backends -``` -curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool -[ - { - "active": true, - "includeInRouter": true, - "localPort": 8081, - "name": "presto1", - "proxyTo": "http://presto1.lyft.com", - "routingGroup": "adhoc" - }, - { - "active": true, - "includeInRouter": true, - "localPort": 8083, - "name": "presto3", - "proxyTo": "http://presto3.lyft.com", - "routingGroup": "adhoc" - } -] -``` -### Activate a backend - -curl -X POST prestogateway.lyft.com/gateway/backend/activate/presto2 + * [Get all backends behind the gateway](/gateway/#get-all-backends-behind-the-gateway) + * [Get active backends behind the Gateway](/gateway/#get-active-backends-behind-the-gateway) + * [Deactivate a backend](/gateway/#deactivate-a-backend) + * [Activate a backend](/gateway/#activate-a-backend) -Verify this by calling get active backends -``` -curl -X GET localhost:8090/gateway/backend/active | python -m json.tool +## Contributing -[ - { - "active": true, - "includeInRouter": true, - "localPort": 8081, - "name": "presto1", - "proxyTo": "http://presto1.lyft.com", - "routingGroup": "adhoc" - }, - { - "active": true, - "includeInRouter": true, - "localPort": 8082, - "name": "presto2", - "proxyTo": "http://presto2.lyft.com", - "routingGroup": "adhoc" - }, - { - "active": true, - "includeInRouter": true, - "localPort": 8083, - "name": "presto3", - "proxyTo": "http://presto3.lyft.com", - "routingGroup": "adhoc" - } -] -``` +Want to help build Presto Gateway? Check out our [contributing documentation](CONTRIBUTING.md) diff --git a/docs/assets/prestogateway_ha_admin.png b/docs/assets/prestogateway_ha_admin.png new file mode 100644 index 00000000..74a595d6 Binary files /dev/null and b/docs/assets/prestogateway_ha_admin.png differ diff --git a/gateway-ha/README.md b/gateway-ha/README.md index aedf0760..bc190ddd 100644 --- a/gateway-ha/README.md +++ b/gateway-ha/README.md @@ -1,7 +1,45 @@ Gateway-HA ========== -How to setup dev environment +### Table of Contents + + * [Gateway-HA](#gateway-ha) + * [Getting Started](#getting-started) + * [Build and run](#build-and-run) + * [Query History UI - check query plans etc.](#query-history-ui---check-query-plans-etc) + * [Gateway Admin UI - add and modify backend information](#gateway-admin-ui---add-and-modify-backend-information) + * [How to setup a dev environment](#how-to-setup-a-dev-environment) + * [Gateway HA API](#gateway-api) + * [Get all backends behind the gateway](#get-all-backends-behind-the-gateway) + * [Delete a backend from the gateway](#delete-a-backend-from-the-gateway) + * [Add a backend to the gateway](#add-a-backend-to-the-gateway) + * [Update backend information](#update-backend-information) + * [Get active all backend behind the Gateway](#get-active-all-backend-behind-the-gateway) + * [Deactivate a backend](#deactivate-a-backend) + * [Activate a backend](#activate-a-backend) + +## Getting Started + +### Build and run +run `mvn clean install` to build `presto-gateway` + +Edit the [config file](../gateway/src/main/resources/config.yml.template) and update the mysql db information. + +``` +cd gateway-ha/target/ +java -jar gateway=ha-{{VERSION}}-jar-with-dependencies.jar server ../config.yml.template +``` +Now you can access load balanced presto at localhost:8080 port. We will refer to this as `prestogateway.lyft.com` + +### Query History UI - check query plans etc. +PrestoGateway records history of recent queries and displays links to check query details page in respective presto cluster. +![prestogateway.lyft.com](../docs/assets/prestogateway_query_history.png) + +### Gateway Admin UI - add and modify backend information +The Gateway admin page is used to configure the gateway to multiple backends. Existing backend information can also be modified using the same. +![prestogateway.lyft.com/admin](../docs/assets/prestogateway_ha_admin.png) + +How to setup a dev environment ---------------------------- Step 1: setup mysql. Install docker and run the below command when setting up first time: @@ -18,7 +56,7 @@ Now open mysql console and install the presto-gateway tables: mysql -uroot -proot123 -h127.0.0.1 -Dprestogateway ``` -Once logged in to mysql console, please run `resources/gateway-ha-presistence.sql` to populate the tables. +Once logged in to mysql console, please run [gateway-ha-persistence.sql](/src/main/resources/gateway-ha-persistence.sql) to populate the tables. Step 2: Edit the configuration `gateway-ha.yml` @@ -27,3 +65,195 @@ Step 3: Add below program argument to class `HaGatewayLauncher` and debug in IDE ```$xslt server /path/to/gateway-ha/src/test/resources/config-template.yml ``` + +## Gateway HA API + +### Get all backends behind the gateway + +`curl -X GET prestogateway.lyft.com/gateway/backend/all | python -m json.tool` +``` +[ + { + "active": true, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto2", + "proxyTo": "http://presto2.lyft.com", + "routingGroup": "adhoc" + } +] +``` +### Delete a backend from the gateway + +``` +curl -v -H "Content-Type: application/json" -d '{"name": "presto3"}' http://prestogateway.lyft.com/gateway/backend/modify/delete +``` + +Verify this by calling get active backends +``` +curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool + +[ + { + "active": true, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto2", + "proxyTo": "http://presto2.lyft.com", + "routingGroup": "adhoc" + } +] + +``` +### Add a backend to the gateway + +``` +curl -v -H "Content-Type: application/json" -d '{"name": "presto3","proxyTo": "http://presto3.lyft.com","active": false,"routingGroup": "adhoc"}' http://prestogateway.lyft.com/gateway/backend/modify/add +``` + +Verify this by calling get active backends +``` +curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool + +[ + { + "active": true, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto2", + "proxyTo": "http://presto2.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + } +] +``` +### Update backend information + +``` +curl -v -H "Content-Type: application/json" -d '{"name": "presto3","localPort": 8084,"proxyTo": "http://presto3.lyft.com","includeInRouter": true,"active": false,"routingGroup": "adhoc"}' http://prestogateway.lyft.com/gateway/backend/modify/add +``` + +Verify if the port number is updated by calling get active backends +``` +curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool + +[ + { + "active": true, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto2", + "proxyTo": "http://presto2.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + } +] +``` +### Get active all backend behind the Gateway + +`curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool` +``` +[ + { + "active": true, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto2", + "proxyTo": "http://presto2.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + } +] +``` +### Deactivate a backend + +`curl -X POST prestogateway.lyft.com/gateway/backend/deactivate/presto2` + +Verify this by calling get active backends +``` +curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool +[ + { + "active": true, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + } +] +``` +### Activate a backend + +`curl -X POST prestogateway.lyft.com/gateway/backend/activate/presto2` + +Verify this by calling get active backends +``` +curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool + +[ + { + "active": true, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto2", + "proxyTo": "http://presto2.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + } +] +``` diff --git a/gateway-ha/gateway-ha-config.yml b/gateway-ha/gateway-ha-config.yml index 2885af98..94089bb4 100644 --- a/gateway-ha/gateway-ha-config.yml +++ b/gateway-ha/gateway-ha-config.yml @@ -1,7 +1,6 @@ requestRouter: port: 8080 name: prestoRouter - cacheDir: /var/log/prestoproxy/cache historySize: 1000 dataStore: diff --git a/gateway-ha/pom.xml b/gateway-ha/pom.xml index f0f88723..e94f8ff4 100644 --- a/gateway-ha/pom.xml +++ b/gateway-ha/pom.xml @@ -19,6 +19,7 @@ 1.8 1.8 + 2.7.4 UTF-8 UTF-8 com.lyft.data.gateway.ha.HaGatewayLauncher @@ -64,23 +65,10 @@ 2.2 - opensymphony - oscache - 2.4.1 - - - javax.jms - jms - - + net.sf.ehcache + ehcache + ${ehcache.version} - - - - - - - diff --git a/gateway-ha/src/main/java/com/lyft/data/gateway/ha/module/HaGatewayProviderModule.java b/gateway-ha/src/main/java/com/lyft/data/gateway/ha/module/HaGatewayProviderModule.java index ee1a604a..66996096 100644 --- a/gateway-ha/src/main/java/com/lyft/data/gateway/ha/module/HaGatewayProviderModule.java +++ b/gateway-ha/src/main/java/com/lyft/data/gateway/ha/module/HaGatewayProviderModule.java @@ -37,8 +37,7 @@ public HaGatewayProviderModule(HaGatewayConfiguration configuration, Environment routingManager = new HaRoutingManager( gatewayBackendManager, - (HaQueryHistoryManager) queryHistoryManager, - getConfiguration().getRequestRouter().getCacheDir()); + (HaQueryHistoryManager) queryHistoryManager); } protected ProxyHandler getProxyHandler() { diff --git a/gateway-ha/src/main/java/com/lyft/data/gateway/ha/router/HaRoutingManager.java b/gateway-ha/src/main/java/com/lyft/data/gateway/ha/router/HaRoutingManager.java index 0d31270c..ced1353b 100644 --- a/gateway-ha/src/main/java/com/lyft/data/gateway/ha/router/HaRoutingManager.java +++ b/gateway-ha/src/main/java/com/lyft/data/gateway/ha/router/HaRoutingManager.java @@ -10,10 +10,8 @@ public class HaRoutingManager extends RoutingManager { HaQueryHistoryManager queryHistoryManager; public HaRoutingManager( - GatewayBackendManager gatewayBackendManager, - HaQueryHistoryManager queryHistoryManager, - String cacheDataDir) { - super(gatewayBackendManager, cacheDataDir); + GatewayBackendManager gatewayBackendManager, HaQueryHistoryManager queryHistoryManager) { + super(gatewayBackendManager); this.queryHistoryManager = queryHistoryManager; } diff --git a/gateway-ha/src/main/resources/activejdbc.properties b/gateway-ha/src/main/resources/activejdbc.properties index c01e5e34..4962bac1 100644 --- a/gateway-ha/src/main/resources/activejdbc.properties +++ b/gateway-ha/src/main/resources/activejdbc.properties @@ -1 +1,2 @@ -cache.manager=org.javalite.activejdbc.cache.OSCacheManager +cache.manager=org.javalite.activejdbc.cache.EHCacheManager + diff --git a/gateway-ha/src/main/resources/template/admin-view.ftl b/gateway-ha/src/main/resources/template/admin-view.ftl index aac95d75..f5396135 100644 --- a/gateway-ha/src/main/resources/template/admin-view.ftl +++ b/gateway-ha/src/main/resources/template/admin-view.ftl @@ -16,7 +16,6 @@ -HELLO
diff --git a/gateway-ha/src/test/java/com/lyft/data/gateway/ha/router/TestQueryHistoryManager.java b/gateway-ha/src/test/java/com/lyft/data/gateway/ha/router/TestQueryHistoryManager.java index 2ad398d0..5b88e89a 100644 --- a/gateway-ha/src/test/java/com/lyft/data/gateway/ha/router/TestQueryHistoryManager.java +++ b/gateway-ha/src/test/java/com/lyft/data/gateway/ha/router/TestQueryHistoryManager.java @@ -7,10 +7,9 @@ import com.lyft.data.gateway.router.QueryHistoryManager.QueryDetail; import java.io.File; +import java.sql.Timestamp; import java.util.List; - import org.javalite.activejdbc.Base; -import org.terracotta.statistics.Time; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -42,8 +41,8 @@ public void testSubmitAndFetchQueryHistory() { queryDetail.setUser("test@ea.com"); queryDetail.setQueryText("select 1"); for (int i = 0; i < 2; i++) { - queryDetail.setQueryId(String.valueOf(Time.absoluteTime())); - queryDetail.setCaptureTime(Time.absoluteTime()); + queryDetail.setQueryId(String.valueOf(System.currentTimeMillis())); + queryDetail.setCaptureTime(System.currentTimeMillis()); queryHistoryManager.submitQueryDetail(queryDetail); } queryDetails = queryHistoryManager.fetchQueryHistory(); diff --git a/gateway-ha/src/test/resources/test-config-template.yml b/gateway-ha/src/test/resources/test-config-template.yml index dd8a2ebb..bdc2280b 100644 --- a/gateway-ha/src/test/resources/test-config-template.yml +++ b/gateway-ha/src/test/resources/test-config-template.yml @@ -1,7 +1,6 @@ requestRouter: port: REQUEST_ROUTER_PORT name: testPrestoRouter - cacheDir: CACHE_DIR historySize: 1000 server: diff --git a/gateway/README.md b/gateway/README.md new file mode 100644 index 00000000..5b731256 --- /dev/null +++ b/gateway/README.md @@ -0,0 +1,168 @@ +# Standalone Gateway + + +### Table of Contents + + * [Standalone Gateway](#standalone-gateway) + * [Getting Started](#getting-started) + * [Build and run](#build-and-run) + * [Query History UI - check query plans etc.](#query-history-ui---check-query-plans-etc) + * [Adhoc vs Scheduled query routing](#adhoc-vs-scheduled-query-routing) + * [Gateway API](#gateway-api) + * [Get all backends behind the gateway](#get-all-backends-behind-the-gateway) + * [Get active backends behind the Gateway](#get-active-backends-behind-the-gateway) + * [Deactivate a backend](#deactivate-a-backend) + * [Activate a backend](#activate-a-backend) + +## Getting Started + +### Build and run +run `mvn clean install` to build `presto-gateway` + +Edit the [config file](src/main/resources/config.yml.template) and update backend urls + +``` +cd gateway/target/ +java -jar gateway-{{VERSION}}-jar-with-dependencies.jar server ../src/presto-gateway/gateway/src/main/resources/config.yml.template +``` +Now you can access load balanced presto at localhost:8080 port. We will refer to this as `prestogateway.lyft.com` + +### Query History UI - check query plans etc. +PrestoGateway records history of recent queries and displays links to check query details page in respective presto cluster. +![prestogateway.lyft.com](../docs/assets/prestogateway_query_history.png) + +### Adhoc vs Scheduled query routing +In the [config](src/main/resources/config.yml.template) +you can specify if a backend cluster is a part of a routing group. +If not specified, cluster will be part of `adhoc` routing group by default. + +PrestoGateway router will route any request to `scheduled` group of clusters if request contains header `X-Presto-Routing-Group: scheduled` and there are clusters present with config `routingGroup: scheduled`. + +If no matching `routingGroup` found, router will route to `adhoc` group of clusters. Please make sure there are clusters under `adhoc` routing group. + +## Gateway API + +### Get all backends behind the gateway + +`curl -X GET prestogateway.lyft.com/gateway/backend/all | python -m json.tool` +``` +[ + { + "active": true, + "includeInRouter": true, + "localPort": 8081, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "includeInRouter": true, + "localPort": 8083, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "includeInRouter": true, + "localPort": 8082, + "name": "presto2", + "proxyTo": "http://presto2.lyft.com", + "routingGroup": "adhoc" + } +] +``` + +### Get active backends behind the Gateway + +`curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool` +``` +[ + { + "active": true, + "includeInRouter": true, + "localPort": 8081, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "includeInRouter": true, + "localPort": 8082, + "name": "presto2", + "proxyTo": "http://presto2.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "includeInRouter": true, + "localPort": 8083, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + } +] +``` +### Deactivate a backend + +`curl -X POST prestogateway.lyft.com/gateway/backend/deactivate/presto2` + +Verify this by calling get active backends +``` +curl -X GET prestogateway.lyft.com/gateway/backend/active | python -m json.tool +[ + { + "active": true, + "includeInRouter": true, + "localPort": 8081, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "includeInRouter": true, + "localPort": 8083, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + } +] +``` +### Activate a backend + +curl -X POST prestogateway.lyft.com/gateway/backend/activate/presto2 + +Verify this by calling get active backends +``` +curl -X GET localhost:8090/gateway/backend/active | python -m json.tool + +[ + { + "active": true, + "includeInRouter": true, + "localPort": 8081, + "name": "presto1", + "proxyTo": "http://presto1.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "includeInRouter": true, + "localPort": 8082, + "name": "presto2", + "proxyTo": "http://presto2.lyft.com", + "routingGroup": "adhoc" + }, + { + "active": true, + "includeInRouter": true, + "localPort": 8083, + "name": "presto3", + "proxyTo": "http://presto3.lyft.com", + "routingGroup": "adhoc" + } +] +``` \ No newline at end of file diff --git a/gateway/pom.xml b/gateway/pom.xml index e2ef6794..36b79a27 100644 --- a/gateway/pom.xml +++ b/gateway/pom.xml @@ -21,7 +21,6 @@ 1.8 UTF-8 UTF-8 - 9.4.9.v20180320 1.3.8 3.5.2 @@ -62,11 +61,6 @@ dropwizard-assets ${dropwizard.version} - - org.ehcache - ehcache - ${ehcache.version} - com.google.inject guice diff --git a/gateway/src/main/java/com/lyft/data/gateway/config/RequestRouterConfiguration.java b/gateway/src/main/java/com/lyft/data/gateway/config/RequestRouterConfiguration.java index ec3b5995..6c484aa4 100644 --- a/gateway/src/main/java/com/lyft/data/gateway/config/RequestRouterConfiguration.java +++ b/gateway/src/main/java/com/lyft/data/gateway/config/RequestRouterConfiguration.java @@ -10,8 +10,7 @@ public class RequestRouterConfiguration { // Name of the routing gateway name (for metrics purposes) private String name; - // Cache dir to store query id <-> backend mapping - private String cacheDir; + private String gatewayStateDir; // Use SSL? private boolean ssl; diff --git a/gateway/src/main/java/com/lyft/data/gateway/module/GatewayProviderModule.java b/gateway/src/main/java/com/lyft/data/gateway/module/GatewayProviderModule.java index baad8f71..1dfc8128 100644 --- a/gateway/src/main/java/com/lyft/data/gateway/module/GatewayProviderModule.java +++ b/gateway/src/main/java/com/lyft/data/gateway/module/GatewayProviderModule.java @@ -40,10 +40,10 @@ public GatewayProviderModule(GatewayConfiguration configuration, Environment env new QueryHistoryManagerImpl(getConfiguration().getRequestRouter().getHistorySize()); this.gatewayBackendManager = new GatewayBackendManagerImpl( - gatewayBackends, getConfiguration().getRequestRouter().getCacheDir()); + gatewayBackends, getConfiguration().getRequestRouter().getGatewayStateDir()); this.routingManager = new DefaultRoutingManager( - gatewayBackendManager, getConfiguration().getRequestRouter().getCacheDir()); + gatewayBackendManager, getConfiguration().getRequestRouter().getGatewayStateDir()); } /* @return Provides instance of RoutingProxyHandler. */ diff --git a/gateway/src/main/java/com/lyft/data/gateway/router/RoutingManager.java b/gateway/src/main/java/com/lyft/data/gateway/router/RoutingManager.java index 8aefd6bf..51cbabb6 100644 --- a/gateway/src/main/java/com/lyft/data/gateway/router/RoutingManager.java +++ b/gateway/src/main/java/com/lyft/data/gateway/router/RoutingManager.java @@ -1,32 +1,28 @@ package com.lyft.data.gateway.router; import com.google.common.base.Strings; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import com.lyft.data.gateway.config.ProxyBackendConfiguration; import com.lyft.data.proxyserver.ProxyServerConfiguration; -import java.io.File; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; + import javax.ws.rs.HttpMethod; import lombok.extern.slf4j.Slf4j; -import org.ehcache.Cache; -import org.ehcache.PersistentCacheManager; -import org.ehcache.config.builders.CacheConfigurationBuilder; -import org.ehcache.config.builders.CacheManagerBuilder; -import org.ehcache.config.builders.ResourcePoolsBuilder; -import org.ehcache.config.units.EntryUnit; -import org.ehcache.config.units.MemoryUnit; - /** * This class performs health check, stats counts for each backend and provides a backend given * request object. Default implementation comes here. @@ -34,29 +30,23 @@ @Slf4j public abstract class RoutingManager { private static final Random RANDOM = new Random(); - private final Cache queryIdBackendCache; + private final LoadingCache queryIdBackendCache; private ExecutorService executorService = Executors.newFixedThreadPool(5); private GatewayBackendManager gatewayBackendManager; - public RoutingManager(GatewayBackendManager gatewayBackendManager, String cacheDataDir) { + public RoutingManager(GatewayBackendManager gatewayBackendManager) { this.gatewayBackendManager = gatewayBackendManager; - - PersistentCacheManager persistentCacheManager = - CacheManagerBuilder.newCacheManagerBuilder() - .with(CacheManagerBuilder.persistence(new File(cacheDataDir, "queryIdBackendMapping"))) - .withCache( - "queryIdBackendPersistentCache", - CacheConfigurationBuilder.newCacheConfigurationBuilder( - String.class, - String.class, - ResourcePoolsBuilder.newResourcePoolsBuilder() - .heap(1000, EntryUnit.ENTRIES) - .offheap(100, MemoryUnit.MB) - .disk(1, MemoryUnit.GB, true))) - .build(true); - this.queryIdBackendCache = - persistentCacheManager.getCache( - "queryIdBackendPersistentCache", String.class, String.class); + queryIdBackendCache = + CacheBuilder.newBuilder() + .maximumSize(10000) + .expireAfterAccess(30, TimeUnit.MINUTES) + .build( + new CacheLoader() { + @Override + public String load(String queryId) { + return findBackendForUnknownQueryId(queryId); + } + }); } protected GatewayBackendManager getGatewayBackendManager() { @@ -70,6 +60,8 @@ public void setBackendForQueryId(String queryId, String backend) { /** * Performs routing to an adhoc backend. * + *

d. + * * @return */ public String provideAdhocBackend() { @@ -105,11 +97,11 @@ public String provideBackendForRoutingGroup(String routingGroup) { * @return */ public String findBackendForQueryId(String queryId) { - String backendAddress = queryIdBackendCache.get(queryId); - if (Strings.isNullOrEmpty(backendAddress)) { - log.error("Could not find mapping for query id {}", queryId); - // for now fall back to the first backend as default - backendAddress = findBackendForUnknownQueryId(queryId); + String backendAddress = null; + try { + backendAddress = queryIdBackendCache.get(queryId); + } catch (ExecutionException e) { + log.error("Exception while loading queryId from cache {}", e.getLocalizedMessage()); } return backendAddress; } diff --git a/gateway/src/main/java/com/lyft/data/gateway/router/impl/DefaultRoutingManager.java b/gateway/src/main/java/com/lyft/data/gateway/router/impl/DefaultRoutingManager.java index f10ea7a0..4df12681 100644 --- a/gateway/src/main/java/com/lyft/data/gateway/router/impl/DefaultRoutingManager.java +++ b/gateway/src/main/java/com/lyft/data/gateway/router/impl/DefaultRoutingManager.java @@ -5,6 +5,6 @@ public class DefaultRoutingManager extends RoutingManager { public DefaultRoutingManager(GatewayBackendManager gatewayBackendManager, String cacheDataDir) { - super(gatewayBackendManager, cacheDataDir); + super(gatewayBackendManager); } } diff --git a/gateway/src/main/resources/config.yml.template b/gateway/src/main/resources/config.yml.template index a0051736..2e6cf978 100644 --- a/gateway/src/main/resources/config.yml.template +++ b/gateway/src/main/resources/config.yml.template @@ -1,7 +1,7 @@ requestRouter: port: 8080 name: prestoRouter - cacheDir: /var/log/prestoproxy/cache + gatewayStateDir: /var/log/prestoproxy/state/ historySize: 1000 backends: diff --git a/gateway/src/test/java/com/lyft/data/gateway/GatewayTestUtil.java b/gateway/src/test/java/com/lyft/data/gateway/GatewayTestUtil.java index aeea5ba9..72b4a6ba 100644 --- a/gateway/src/test/java/com/lyft/data/gateway/GatewayTestUtil.java +++ b/gateway/src/test/java/com/lyft/data/gateway/GatewayTestUtil.java @@ -34,7 +34,7 @@ public static String buildGatewayConfigPath( String configStr = sb.toString() .replace("REQUEST_ROUTER_PORT", String.valueOf(routerPort)) - .replace("CACHE_DIR", tempDir.getAbsolutePath()) + .replace("GATEWAY_STATE_DIR", tempDir.getAbsolutePath()) .replace( "APPLICATION_CONNECTOR_PORT", String.valueOf(30000 + (int) (Math.random() * 1000))) .replace("ADMIN_CONNECTOR_PORT", String.valueOf(31000 + (int) (Math.random() * 1000))); diff --git a/gateway/src/test/resources/test_config_template.yaml b/gateway/src/test/resources/test_config_template.yaml index d8bcba73..363c6137 100644 --- a/gateway/src/test/resources/test_config_template.yaml +++ b/gateway/src/test/resources/test_config_template.yaml @@ -1,7 +1,7 @@ requestRouter: port: REQUEST_ROUTER_PORT name: testPrestoRouter - cacheDir: CACHE_DIR + gatewayStateDir: GATEWAY_STATE_DIR historySize: 1000 server: