DoorDash se enorgullece de ofrecer una experiencia de prácticas en la que los becarios se integran plenamente con los equipos de ingeniería y obtienen el tipo de experiencia real en el sector que no se enseña en un aula. Para mostrar algunas de las experiencias de nuestros becarios del verano de 2021, hemos reunido esta colección de proyectos de becarios.
Contenido:
- Optimizing Two Factor Authentication To Improve The User Experience - By Nir Levin
- Gradually Releasing a New Onboarding Feature With Email Bucketing - By Austin Leung
- Building an efficient lookup system to speed up DashMart receiving times - By Anna Sun
- Building for data dependency discoverability at scale - By Michael Yu
- Reducing database outages by persisting order data from PostgresDB to Amazon S3 - By Austin Kim
Optimizar la autenticación de dos factores para mejorar la experiencia del usuario
Por Nir Levin
DoorDash uses two-factor authentication (2FA) as a means of preventing bad actors from being able to log into innocent user accounts and making purchases on their behalf. Of course, this shouldn’t be a surprise - the vast majority of companies have a consumer login which employs some form of 2FA in order to prevent these unauthorized account takeovers (ATOs) from happening. The main challenge we set out to tackle is determining the right level of risk to send out a 2FA. We need a good balance so that fraudsters are blocked but we also minimize the number of good users who experience the 2FA friction.
Cómo se utiliza la 2FA
El objetivo de la 2FA es permitir que los buenos usuarios demuestren que son los titulares legítimos de la cuenta y detener las ATOs por parte de estafadores que no son propietarios de la cuenta a la que intentan acceder. Lo más habitual es que las ATO se produzcan cuando un malhechor se hace con las credenciales de un buen usuario a través de métodos como el phishing, la reutilización de credenciales filtradas o la apropiación de la cuenta de correo electrónico de un usuario. Para evitar el acceso no autorizado, se puede enviar una solicitud 2FA cuando el usuario inicia sesión. La 2FA suele ser un mensaje de texto enviado al dispositivo del usuario. Como el estafador sólo tiene las credenciales del usuario y no su dispositivo, no podrá iniciar sesión y hacerse con el control de la cuenta.
El problema de lanzar una red demasiado grande
En teoría, DoorDash podría enviar una solicitud de 2FA cada vez que un usuario inicia sesión. Aunque esto maximizaría la seguridad, también interrumpe la experiencia del usuario, lo que puede hacer que los clientes frustrados dejen de usar la plataforma. Para minimizar el uso de solicitudes 2FA, sólo las emitimos cuando existe un alto riesgo de que se produzca un ATO. Para optimizar la captura de los defraudadores al tiempo que se minimiza el envío de la 2FA a los buenos usuarios, tuvimos que actualizar el algoritmo para decidir cuándo emitir una 2FA.
Creación de algoritmos
El primer paso para emitir una solicitud 2FA fue recopilar y analizar los metadatos de usuario en la tabla de la base de datos de producción mediante un trabajo de extracción, transformación y carga (ETL). Creamos reglas que utilizarían los atributos de usuario almacenados en la base de datos para evaluar el riesgo de que cada inicio de sesión fuera o no un ATO. Estas reglas forman parte del motor de riesgo de fraude de DoorDash. Si el inicio de sesión de un usuario infringe estas reglas, como el inicio de sesión en un nuevo dispositivo para el que el ID no está ya presente en nuestra base de datos, el motor de riesgo podría reaccionar en tiempo real y emitir una solicitud de 2FA. Hay varias características de inicio de sesión, como el ID del dispositivo, que se introducen en el motor de riesgo para que pueda determinar si el usuario es lo suficientemente fiable como para continuar sin 2FA. El nuevo algoritmo introduce más características, a las que el motor de riesgo accede a través de tablas suplementarias creadas por el trabajo ETL.
Resultados
Según nuestra experimentación, la difusión de nuestro nuevo algoritmo se tradujo en una reducción relativa del 15% en las solicitudes de 2FA. Además, se produjo un notable aumento de usuarios que iniciaron sesión y realizaron entregas con éxito. Tampoco aumentaron las devoluciones de cargos, lo que ocurriría si los estafadores completaran con éxito la toma de control de cuentas, debido a nuestro nuevo algoritmo, y realizaran pedidos.
Averiguar cómo proteger las cuentas con 2FA sin dejar de garantizar una experiencia de usuario positiva puede ser útil para muchas empresas que buscan tener un inicio de sesión digital seguro.
Lanzamiento gradual de una nueva función de incorporación con Email Bucketing
Por Austin Leung
Para mejorar la selección de DoorDash, necesitamos un proceso de incorporación sólido. Aunque la mayoría de las incorporaciones de comerciantes son estándar, para ampliar la selección necesitamos crear un nuevo tipo de experiencia de incorporación para los comerciantes que no utilizan Dashers para la entrega. Esta experiencia debía probarse antes de ponerla en marcha para todos los comerciantes. Aquí hablaremos de cómo creamos una nueva experiencia con herramientas internas y nos decidimos por una solución de agrupación para ofrecerla gradualmente a los comerciantes.
Por qué tuvimos que abandonar Formstack para la incorporación de comerciantes con autoentrega
Anteriormente, los comerciantes que querían completar un proceso de incorporación de autoservicio tenían que utilizar Formstack, un servicio de terceros similar a Google Forms. Aunque Formstack nos ha servido bien hasta ahora, hay importantes puntos débiles que nos gustaría abordar en el futuro para mejorar la experiencia de incorporación:
- Normas de seguridad: Formstack no cumple con SOC II Tipo 2 que ya no cumple con nuestros requisitos.
- Velocidad de carga: bastante lenta según los comentarios negativos de los usuarios.
- No hay asistencia por chat del equipo de ventas: a menudo los usuarios se atascan y necesitan ayuda para avanzar sin problemas.
- Fiabilidad insuficiente: Los operadores de DoorDash a menudo tenían que solucionar problemas, lo que no era lo ideal
En general, estos problemas creaban el riesgo de que la tecnología fuera responsable de la pérdida de registros de comerciantes cada semana, lo que podría perjudicar la experiencia de incorporación.
Para ofrecer una mejor experiencia de usuario a los comerciantes, decidimos crearla nosotros mismos aprovechando la aplicación Self Serve Merchant Onboarding (SSMO) existente. La SSMO existente ya contaba con un flujo para dar soporte a los comerciantes del mercado, por lo que se presentó la oportunidad de adaptarla para un flujo de autoservicio independiente.
En DoorDash no basta con crear una nueva función, sino que realizamos experimentos para demostrar que la nueva experiencia es mejor y hacemos un despliegue gradual para mantener la fiabilidad. Para probar esta función, establecimos una comparación con la solución anterior. Si nuestras métricas de éxito, como las experiencias de incorporación satisfactorias, aumentaban y no había problemas, podíamos escalar con seguridad el nuevo formulario a una parte mayor del tráfico global.
Utilizamos el bucketing porque:
- Nos permitió minimizar el impacto de cualquier problema, ya que los problemas sólo afectaron a la experiencia del grupo más pequeño que fue redirigido a la OMPE.
- Nos permitió revertir todo el tráfico a Formstack inmediatamente, si se producía algún problema, mitigando el impacto negativo.
- Puede ayudarnos a demostrar que la nueva función no sólo es positiva para la tasa de conversión, sino que además tiene mejores métricas de fiabilidad que la experiencia de Formstack.
Para llevar a cabo este lanzamiento gradual, necesitábamos averiguar con qué rapidez aumentaríamos el tráfico hacia la nueva solución y cómo impulsaríamos esa transición.
Encontrar la mejor llave de cubo para dividir el tráfico
En cuanto a la implementación de la segmentación en sí, DoorDash utiliza una biblioteca para configurar valores dinámicos que podemos introducir en nuestro código. Hay muchas posibilidades, como especificar la clave de la cesta, el porcentaje de cada cesta y asignar porcentajes específicos a submercados individuales. Una de nuestras principales decisiones de diseño fue identificar la clave de cubo entre las muchas opciones.
Estos fueron nuestros principales criterios para seleccionar nuestra llave cubo:
- Identificable en cada registro de incorporación para que pudiéramos utilizarlo para redirigir a la experiencia correcta.
- Introducida por el usuario. En el desarrollo y las pruebas, queríamos utilizar la clave de cubo para decidir a qué experiencia seríamos redirigidos. Nuestro objetivo era tener una subcadena opcional en la clave de bucket que forzara la sesión a un determinado bucket. Esto nos proporcionaría un entorno estable en lugar de esperar que se nos redirigiera a una experiencia específica.
- Coherencia en las múltiples incorporaciones de un comerciante. A menudo, los comerciantes no completan su incorporación inicial, sino que vuelven más tarde para comenzar una nueva incorporación. Queremos asegurarnos de que cada comerciante tenga siempre la misma experiencia a la que se ha acostumbrado.
Para solucionarlo, consideramos tres opciones para nuestra clave de cubo:
- División por UUID
- División por ubicación
- Dividir por correo electrónico
La opción natural sería utilizar el UUID de la sesión del comerciante para el bucketing, ya que generamos un UUID para cada onboarding. Sin embargo, esto incumplía nuestros requisitos:
- No era coherente. Como los UUID se identificaban con cada sesión, un usuario podía volver y tener una experiencia totalmente nueva.
- No era fácil controlar el tráfico. En el desarrollo y las pruebas, a menudo pretendíamos entrar en la nueva experiencia de la OMPE, pero se agrupaban en Formstack. Idealmente, querríamos asegurarnos de que los UUID que terminan en una determinada cadena de caracteres fueran agrupados en determinadas experiencias. Sin embargo, como el UUID de una sesión se genera automáticamente en lugar de ser introducido por el usuario, esto no era posible.
A continuación, consideramos la posibilidad de agrupar por ubicación, ya que ésta se introducía como la dirección de la empresa en el formulario de contacto de la página de destino. Si utilizábamos el submercado de la ubicación del comerciante como clave de agrupación, los comerciantes siempre tendrían una experiencia coherente. Sin embargo, nuestra preocupación con el uso de esta clave de agrupación era que para realizar una verdadera prueba A/B, queríamos que los usuarios se dividieran sin que la agrupación por submercado fuera un factor de confusión.
En su lugar, decidimos basarnos en los correos electrónicos. Los comerciantes rellenarían el formulario con su dirección de correo electrónico y nosotros podríamos redirigirlos a la experiencia adecuada en función de ella. El uso del correo electrónico como clave satisface todos nuestros criterios iniciales, ya que se especifica al principio de cada incorporación, se guarda en el registro de incorporación y es coherente para los comerciantes que deseen reiniciar su incorporación. También podríamos utilizar el correo electrónico para forzar que cualquier usuario que termine su correo electrónico en una determinada cadena sea colocado en un cubo específico. De esta forma podríamos anular la proporción de tráfico que se supone que entra en cada experiencia, y proceder con el desarrollo y las pruebas sin problemas.
El éxito de esta solución
Hemos sido capaces de desarrollar y probar con éxito nuestra solución a gran velocidad, habiendo construido y desplegado el nuevo flujo de autoentrega en el transcurso de 12 semanas. Gracias a la facilidad de uso de la agrupación por correo electrónico, hemos podido realizar pruebas exhaustivas incluso con personas ajenas a la ingeniería. El despliegue comenzó con todo el tráfico dirigido a Formstack y se ha incrementado al 10%, 25% y 50% de los comerciantes que acceden a la autoentrega de OSSM. A medida que realicemos nuestras pruebas A/B, esperamos seguir observando un aumento de la tasa de conversión y de la fiabilidad. Nuestro objetivo actual es un aumento relativo del 29% en la tasa de conversión y una reducción de 14 veces en el tiempo de inactividad.
Durante este proyecto, hemos aprendido que el bucketing se realiza mejor en un entorno altamente controlado en el que se pueden controlar las diferentes experiencias que obtienen los usuarios. Para DoorDash y otras organizaciones basadas en datos, el despliegue gradual es una necesidad para determinar el impacto de cualquier nueva característica frente a las métricas de éxito. Funciones como la autoentrega en la OMPE pueden adaptarse si tienen éxito, lo que garantiza que el producto mejore constantemente. La selección de una clave de cubo adecuada es una herramienta inestimable para lograrlo, ya que nos permite iterar rápidamente y desplegar de forma fiable y sin interrupciones.
Creación de un sistema de búsqueda eficaz para acelerar los tiempos de recepción de DashMart
Por Anna Sun
En agosto de 2020, DoorDash lanzó DashMart, una tienda exclusiva de DoorDash que almacena de todo, desde artículos de conveniencia y tienda de comestibles hasta productos personalizados, artículos de emergencia, artículos para el hogar y más.
Los asociados de DashMart recogen los pedidos de los clientes del mercado de DoorDash y los empaquetan, y un Dasher viene a recoger el pedido y entregarlo al cliente. Para que DashMart fuera más eficiente, necesitábamos actualizar la interfaz de usuario del asociado de DashMart para que los pedidos de reposición que reponen nuestro inventario pudieran procesarse mejor y el inventario de DashMart se actualizara correctamente.
Inicialmente, el proceso de recepción de envíos en el almacén para la reposición de artículos era manual y aún no estaba automatizado. Esto lo hacía lento y propenso a errores humanos.
Para iniciar el proceso de admisión de pedidos de reposición, antes los asociados tenían que buscar e introducir manualmente un ID de pedido, que contenía todos los datos sobre lo que se había pedido y que luego podía añadirse al inventario de DashMart.
Para reducir los errores humanos, actualizamos la herramienta de interfaz de usuario para que pudiera buscar automáticamente el ID de pedido necesario en la base de datos, en lugar de que el asociado tuviera que dedicar tiempo a buscar el ID manualmente. Esta función evita confusiones y errores humanos a la hora de aceptar pedidos de reposición y añadirlos al inventario de DashMart.
Implementamos esta función mostrando los datos de los pedidos de las instalaciones y desglosándolos por proveedores, mediante las API GET. Gracias a estas integraciones y a algunos ajustes en el frontend, los operarios pudieron utilizar este sistema para introducir identificadores de pedidos de reposición y asegurarse de que los artículos se añadían rápidamente al inventario.
Teniendo en cuenta que entre 400 y 500 operadores utilizan a diario este portal de recepción de pedidos, este cambio ha tenido una enorme repercusión y ha mejorado enormemente la productividad. Al ahorrar a los operadores decenas de minutos cada día, nos aseguramos de que las entregas de DashMart se realicen lo antes posible".
Construir la descubribilidad de las dependencias de datos a escala
Por Michael Yu
A medida que la infraestructura de datos de DoorDash crece para dar soporte a más de 20 millones de consumidores al mes en cuatro países, mantener el linaje de los datos se convierte en un reto cada vez mayor. Comprender de dónde proceden los datos específicos, cómo los transforman nuestros sistemas y en qué bases de datos se escriben es fundamental para que nuestra plataforma logística funcione sin problemas. Para dar respuesta a esta necesidad, integramos el linaje de datos en una nueva plataforma basada en el proyecto de código abierto Amundsen.
Problemas para descubrir dependencias de datos a escala
Antes de crear esta solución, descubrir los productores de datos y los consumidores de los mismos requería una importante investigación manual. Comprender el contexto que subyace a las fuentes de datos es esencial para tomar decisiones basadas en datos. Esto hace que sea difícil para los ingenieros y analistas tomar decisiones basadas en datos, ya que descubrir el contexto detrás de sus fuentes de datos requiere una investigación manual significativa. Por ejemplo, supongamos que tenemos una columna en una tabla que contiene el volumen medio de pedidos de los últimos 90 días. Si observamos una incoherencia en esa métrica, el proceso para descubrir la causa raíz puede implicar rastrear el trabajo ETL que escribe en esa tabla, averiguar qué consultas SQL se ejecutaron en ese trabajo ETL y encontrar las tablas de origen de esas consultas SQL. Este proceso podría repetirse varias veces si la causa raíz no es una fuente de datos ascendente directa, utilizando importantes recursos de ingeniería.
Creación de una plataforma de descubrimiento de datos
Nuestra nueva plataforma, a la que llamamos Catálogo de Datos, indexa todos los procesos de datos de DoorDash para aumentar su visibilidad. Permite a los usuarios encontrar rápidamente las fuentes de datos que les interesan y ver sus dependencias ascendentes y descendentes.
La plataforma se centra en dos áreas distintas, las dependencias entre los trabajos ETL y entre las tablas alojadas por Snowflake, un proveedor de infraestructura de datos de DoorDash. Hay dos fuentes de datos que leemos para detectar las dependencias entre los trabajos ETL: El código de definición ETL y la base de datos de metadatos Apache Airflow. Obtener el linaje a través de las tablas de Snowflake es una tarea complicada ya que, a diferencia de los trabajos ETL, no hay dependencias explícitas definidas. En su lugar, tenemos que mirar las consultas SQL que se ejecutan en Snowflake. Utilizando un analizador SQL que ingiere consultas SQL sin procesar, podemos extraer la información de las tablas de origen y destino.
Impacto
La integración del linaje de datos en el Catálogo de datos proporciona a ingenieros y analistas un medio unificado de recuperar todas las dependencias ascendentes y descendentes de cualquier fuente de datos en la que estén interesados. Esta plataforma elimina por completo la necesidad de rastrear el código, las consultas SQL o los registros. En última instancia, nuestro catálogo de datos allana el camino para obtener un linaje completo de extremo a extremo, permitiendo a cualquiera rastrear el flujo de datos a medida que se mueve a través de cuadros de mando, métricas, servicios y trabajos ETL.
Reducción de las interrupciones de la base de datos mediante la persistencia de los datos de pedidos de PostgresDB a Amazon S3.
Por Austin Kim
Amazon Web Services (AWS) aconseja mantener las tablas de las bases de datos por debajo de los 500 GB, pero la tabla de la base de datos que almacena todos los pedidos realizados en DoorDash superaba constantemente este límite. Una solución a corto plazo, archivar los datos de más de 90 días, no era escalable, especialmente a medida que DoorDash crece. Analizando el uso de los datos, descubrimos que más del 80% de los datos procedían de una única columna JSON. Nuestra solución a largo plazo era persistir esa columna JSON en el servicio de almacenamiento simple (S3) de Amazon.
Uno de los retos de esta solución consistía en garantizar que todos los casos de uso de JSON obtuvieran los datos de S3 y no dependieran de la base de datos. Otro reto era obtener el JSON de S3 de forma que no se congelara ni añadiera riesgo de fallo a los flujos de trabajo que procesan los pedidos. Por último, dado que esta operación afectará a millones de pedidos realizados en DoorDash, necesitamos implementarla en producción de forma segura y sin riesgo de bloquear los flujos de trabajo que procesan los pedidos.
La primera parte de esta solución requería la persistencia del JSON en S3. Este proceso comienza cuando uno de nuestros microservicios recibe una solicitud gRPC que contiene los datos de la carga útil del pedido. A continuación, nuestro microservicio utiliza esa carga útil para crear un objeto de pedido en la base de datos. Normalmente almacenamos toda la carga útil del pedido, pero ahora enviamos los datos a S3. A continuación, recuperamos la dirección S3 del archivo donde almacenamos el JSON y guardamos ese enlace en la base de datos para poder acceder a él en el futuro. A continuación, implementamos manejadores de excepciones y tiempos de espera que terminan y reintentan la solicitud de S3 si se está estancando durante demasiado tiempo, asegurándose de que una congelación en S3 no congelará todo el flujo de trabajo.
Nuestra solución reduce en más de un 80% los datos almacenados en la tabla de pedidos. Esta reducción disminuye significativamente el riesgo de nuestra tabla de una interrupción de la base de datos y ya no tendrá que archivar pedidos para resolver este problema. Hemos añadido un nuevo punto final gRPC para facilitar el acceso a microservicios externos que necesitan el objeto de pedido y los JSON potencialmente relacionados que ahora se almacenan en S3, lo que lo hace más eficiente y modularizado para usos del JSON de pedido fuera de las integraciones de comerciantes.